Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
选择txt文档的多行并在python中写入新文本文档时出现问题_Python - Fatal编程技术网

选择txt文档的多行并在python中写入新文本文档时出现问题

选择txt文档的多行并在python中写入新文本文档时出现问题,python,Python,我是个业余爱好者。我有一个文本文件,列出了数千行的信息,我正试图选择一行和下面的2-3行的基础上,他们是否匹配的模式。 我已从原始文件中筛选出该文件,以仅包含我感兴趣的文件部分,因此我当前的文件如下所示: trig1.RESP: stim4: silence.wav trig1.RESP: trig6.RESP: 1 trig1.RESP: trig1.RESP: trig5.RESP: 1 stim5: silence.wav trig1.RESP: trig6.RESP: 1 st

我是个业余爱好者。我有一个文本文件,列出了数千行的信息,我正试图选择一行和下面的2-3行的基础上,他们是否匹配的模式。 我已从原始文件中筛选出该文件,以仅包含我感兴趣的文件部分,因此我当前的文件如下所示:

trig1.RESP: 
stim4: silence.wav 
trig1.RESP: 
trig6.RESP: 1 
trig1.RESP:
trig1.RESP: 
trig5.RESP: 1
stim5: silence.wav
trig1.RESP:
trig6.RESP: 1
stim3: silence.wav
trig1.RESP:
stim5: silence.wav
trig1.RESP:
trig6.RESP: 1
诸如此类。。。 基本上,我要做的是写下每一行中包含silence.wav部分的内容,然后再写下后面的两行。我使用了以下代码:

parsed_output = open("name-of-file-to-be-written", "w")
filtered_input = open("name-of-file-that-has-above-data", "r")
for line in filtered_input:
    if "silence.wav" in line and "trig1" in filtered_input.next():
        parsed_output.write(line)
        parsed_output.write(filtered_input.next())
parsed_output.close()
这在大多数情况下都很好,因为它打印了silence.wav行和具有响应的行(我最感兴趣的部分,此时响应之前的trig1不太重要)。然而,我遇到的问题是,当线路走到:

stim3: silence.wav
trig1.RESP: 
stim5: silence.wav
由于我的输出随后将写入stim3(当前行)和stim5(跳过trig1后的下一行),因此我认为它将转到下一个“stim:silence.wav”并跳过stim5,因为它在写入时包含在上一个命令中。 我希望在stim5之后显示trig6.RESP:1,但由于我描述的原因,我的输出没有显示它。 有没有办法让它不跳过那个刺激


抱歉,如果这真的很长。提前谢谢你

像这样的怎么样?(完全未经测试)

count=3
对于过滤的_输入中的行:
如果行中有“silent.wav”:
计数=0
其他:
计数+=1

如果计数一种可能的方法是使用a,这样您可以一次跟踪三行:

import collections

parsed_output = open("name-of-file-to-be-written", "w")
filtered_input = open("name-of-file-that-has-above-data", "r")

window = collections.deque([None]*3, maxlen=3)
for line in filtered_input:
    window.append(line)
    if 'silence.wav' in window[0]:
        parsed_output.write(window[0])
        # only output next two lines if they don't also contain 'silence.wav'
        if 'silence.wav' not in window[1]:
            parsed_output.write(window[1])
            if 'silence.wav' not in window[2]:
                parsed_output.write(window[2])
# following if/elif in case last or second to last line contain 'silence.wav'
if 'silence.wav' in window[1]:
    parsed_output.write(window[1])
    parsed_output.write(window[2])
elif 'silence.wav' in window[2]:
    parsed_output.write(window[2])
parsed_output.close()
如果为deque提供
maxlen
参数,则在向一端添加其他元素时,会从另一端弹出一个元素,例如:

>>> x = collections.deque([1, 2, 3], maxlen=3)
>>> x
deque([1, 2, 3], maxlen=3)
>>> x.append(4)
>>> x
deque([2, 3, 4], maxlen=3)
>>> x.append(5)
>>> x
deque([3, 4, 5], maxlen=3)

这允许您迭代文件,但以方便的方式保存读取的最后3行。
窗口的第一个元素与您的条件匹配时,只要输出匹配的行和以下两行,只要它们与您的条件不匹配。

我尝试将其转换为psuedocode时说:

For each (Line) {
      If Next Line is "Trig1" AND Current Line is "silence.wav"
          Log it
}
## And We're Done
(请随意在这里纠正我)


你错过了Trig6,因为你要的是下一行不存在的内容。你能把它改写成向后引用而不是向前引用,然后让它解决你的问题吗

您应该真正学习正则表达式的使用(模块re)
当一个人想要分析文本时,它是强制性的

查看它允许执行的操作:

import re

ss = """trig1.RESP: 
stim4: silence.wav 
trig1.RESP: 
trig6.RESP: 1 
trig1.RESP:
trig1.RESP: 
trig5.RESP: 1
stim5: silence.wav
trig1.RESP:
trig6.RESP: 1
stim3: silence.wav
trig1.RESP:
stim5: silence.wav
trig1.RESP:
trig6.RESP: 1

stim777: silence.wav
stim111: silence.wav 
trig1.RESP: 
trig6.RESP: 1
trig1.RESP: 
trig6.RESP: 1"""

pat = ('^(.+silence.wav.*)(?<! ) *\n'
       '(?:(?!.*silence.wav)(.*)(?<! ) *\n)?'
       '(?:(?!.*silence.wav)(.*)(?<! ) *)?')

RE = re.compile(pat,re.MULTILINE)

for tugr in RE.findall(ss):
    print tugr
然后你可以用这些行元组做你想做的

pat是一个字符串,用作定义正则表达式的模式。
RE是一个已编译的正则表达式,它是一个具有方法搜索匹配findall等的对象

括号
()
定义一个组。
组捕获文本的某些部分。 但是
(?:)
定义了一个组,该组不捕获它匹配的文本部分。对文本的一部分进行操作很有用,例如将限定符
*
+
放在组的末尾

当第三行有“silence.wav”时,它必须保持不匹配, 当第二行有“silence.wav”时,只有第一行必须匹配。 这就是为什么在模式的两个地方有
(?*silence.wav)
部分

^
是一个符号,意思是“字符串的开始”
^
带有标志
re.MULTILINE
表示“行的开始”

部分<代码>(模式的)是不捕获行结尾的空白空间。

模式中的点
表示除LF字符外的“任何字符”

\n

如果您需要,我可以回答您的其他问题。

这很聪明,但它不会将某些行写入两次吗?此外,在循环结束时可能会进行检查,以确保倒数第二行不会触发写入。只是为了解决这些问题而进行编辑,我无法从问题中判断是否要复制行是否需要,但它们可能不应该在那里。请忽略我的(现在已删除)注释。这是不正确的。小旁注:我建议你关闭所有打开的文件。最好的方法是使用
语句。哦,天哪,这太简单了。它也起作用了!谢谢谢谢谢谢!谢谢你的建议。我想你也是对的。下一步,学习正则表达式。明白了。:)
('stim4: silence.wav', 'trig1.RESP:', 'trig6.RESP: 1')
('stim5: silence.wav', 'trig1.RESP:', 'trig6.RESP: 1')
('stim3: silence.wav', 'trig1.RESP:', '')
('stim5: silence.wav', 'trig1.RESP:', 'trig6.RESP: 1')
('stim777: silence.wav', '', '')
('stim111: silence.wav', 'trig1.RESP:', 'trig6.RESP: 1')
\n