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