re.findall不匹配所有匹配

时间:2015-11-10 22:55:24

标签: python regex

我需要解析一个大文本文件,寻找这样的模式:

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数字。

我犯的错误是什么?

2 个答案:

答案 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位或更多位数。