我需要解析一个大文本文件,寻找这样的模式:
string='Path Group: sclk ;djlasfhv slack 5t45545 545 (VIOLATED) -0.8568 Path Group: sclk ;djlasfhv slack (VIOLATED) -0.88 Path Group: sclkasfhv slack (VIOLATED) -0.121'
violation = re.findall('Path Group: sclk.*VIOLATED\)\s*(-[0-9]\.[0-9]+)', string)
这只打印最后一个-0.121。我期待[-0.8568,-0.88,-0.121]
P.S。我刚刚给出了一个示例字符串。实际文件非常庞大。我正在寻找我的正则表达式中字符串后面的所有-ve数字。
我犯的错误是什么?
答案 0 :(得分:2)
让它变得非贪婪。你的正则表达式中存在的.*
是贪婪的,它尽可能匹配所有的角色。所以这将匹配所有,-[0-9]\.[0-9]+
模式应该捕获最后一个数字。
violation = re.findall(r'Path Group: sclk.*?VIOLATED\)\s*(-[0-9]\.[0-9]+)', string)
^
示例:的
>>> import re
>>> string='Path Group: sclk ;djlasfhv slack 5t45545 545 (VIOLATED) -0.8568 Path Group: sclk ;djlasfhv slack (VIOLATED) -0.88 Path Group: sclkasfhv slack (VIOLATED) -0.121'
>>> re.findall(r'Path Group: sclk.*?VIOLATED\)\s*(-[0-9]\.[0-9]+)', string)
['-0.8568', '-0.88', '-0.121']
答案 1 :(得分:2)
比懒惰匹配更好,更有效的正则表达式
violation = re.findall(r'Path Group: sclk[^V]*(?:V(?!IOLATED\))[^V]*)*VIOLATED\)\s*(-[0-9]\.[0-9]+)', string)
请参阅IDEONE demo
请参阅regex demo
它基于Jeffrey E. F. Friedl's "unrolling the loop" method,基本上与具有延迟匹配的版本相同,但更有效:
Path Group: sclk
- 文字字符序列[^V]*(?:V(?!IOLATED\))[^V]*)*VIOLATED\)
- 第一个“VIOLATED”\s*
- 0个或更多空格(-[0-9]\.[0-9]+)
- 捕获到第1组-
,然后是数字,然后是句点,然后是1位或更多位数。