之前可能已经提出过这个问题,但这些问题与我的情况不符。我已经完成了大部分工作,但没有一个解决方案有所帮助。
所以,这是问题所在。我有一个包含大量行的文本文件。 以下是该文件的示例:
yyyyyy=xxxx
yyyyyy=xxxxxxxx
Sun Oct 22 15:19:23 PDT 2017
calling sequenc node
++ entering node aaa ( )
Sun Oct 22 15:19:23 PDT 2017
lines xxxxxxxx
calling wroot.bat
++ entering node bbb (xxx )
Sun Oct 22 15:19:23 PDT 2017
xxxxxxxxxxxxxx
calling bsod.bat
xaaaaa
bbbbb
tttttt
bbb completed successfully
-- exiting node bbb
++ entering node ccc (yyyy )
Sun Oct 22 15:19:35 PDT 2017
xxxxxxxxxxxxxxxxx
calling wpretest.bat
现在,我想从调用部分(包括)中提取行到已完成的成功行之上的行。另外,我想在只有++开头的时候提取行。没有。呼叫后的线路各不相同它可能有一个空白,2行或更多行。如果它后面没有行,我只想提取调用行。如果在下一行成功完成,那么我也想提取单个调用行。如果在调用行之间有其他行并且已成功完成,我想提取所有这些行。
这是我和正则表达式一起尝试的代码(似乎没有用)
with open('myfile.txt','r') as log:
for line in log:
match = re.search(node_name_pattern, line)
if line.startswith('++') and match:
node_name.append(match.group())
nn=match.group()
match2 = re.search(node_parameter, line)
if line.startswith('++') and match2:
parameter.append(match2.group())
start_time.append(log.next().strip())
features.append(log.next().strip())
if "calling" in line :
content.append(line.strip())
这是预期的输出:
calling wroot.bat
calling bsod.bat,
xaaaaa,
bbbbb,
tttttt
calling wpretest.bat
如果你想要一个regex
这应该工作:
r'(?<=\n)calling.*?(?=\n[^\n]*completed succ[^\n]*\n|\n\+\+|\s*\Z)'
导致:
>>> bla = open('bla').read()
>>> re.findall(r'(?<=\n)calling.*?(?=\n[^\n]*completed succ[^\n]*\n|\n\+\+|\s*\Z)',bla,re.DOTALL)
['calling sequenc node\n', 'calling wroot.bat \n', 'calling bsod.bat \nxaaaaa\nbbbbb\ntttttt', 'calling wpretest.bat']
打破正则表达式
所以你可以玩它:
(?<=\n)calling
- 如果它紧跟在换行符之后,请查找“呼叫”一词。.*
继续非贪婪地匹配任何东西(?=...|...|...)
之一(|
意味着或):
一个。 \n[^\n]*completed succ[^\n]*\n
包含“完成succ”的行。这本质上是一个换行符,就像你想要的许多非换行符,直到“完成succ”,更多的字符,最后是一个新行。可能结束在completed succ
部分,因为我不关心匹配这一行的其余部分,现在我考虑它。
湾\n\+\+
以“++”开头的换行符。
C。 \s*\Z
任何数量的空格字符(\ n,“”,\ t等),直到整个字符串\Z
结束。我会考虑使用循环,例如:
res = []
inside = False
with open('bla') as bla:
for line in bla:
if inside:
if line.startswith('++') or "completed successfully" in line:
inside = False
else:
res[-1].append(line)
elif line.startswith("calling"):
res.append([line])
inside = True
也许错误检查inside==False
如果该行以calling
开头,以防万一。