是否可以在使用贪婪字符时重新找到最小匹配

时间:2009-09-15 18:07:12

标签: python regex

免责声明:我不是正则表达专家。

我正在使用Python re模块在许多htm文件上执行正则表达式匹配。其中一种模式是这样的:

<bla><blabla>87765.*</blabla><bla>

我遇到的问题是,不是找到所有(比如说)五次出现的模式,而是只找到一个。因为它使用第一次出现的<bla><blabla>87765部分和页面中最后一次出现的</blabla><bla>部分将所有出现次数合并为一次。

有没有办法告诉重新找到最小的匹配?

4 个答案:

答案 0 :(得分:13)

您可以在模式中使用不情愿的限定符(有关详细信息,请参考*?+???运算符上的python documentation

<bla><blabla>87765.*?</blabla><bla>

或者,从可能匹配的字符中排除<

<bla><blabla>87765[^<]*</blabla><bla>
如果<blabla></blabla>之间没有子标记,则

答案 1 :(得分:2)

Python re模块支持非同步匹配。您只需在通配符模式的末尾添加?,例如.*?。您可以在this HOWTO了解详情。

答案 2 :(得分:1)

I believe the regex
<bla><blabla>87765.*?</blabla><bla>
can produce catastrophic backtracking.

Instead, use:
<bla><blabla>87765[^<]*</blabla><bla>

Using atomic grouping (I'm not sure Python supports this), 
the above regex becomes 
<bla><blabla>(?>(.*?<))/blabla><bla>

正则表达式引擎离开组后,(?&gt; ...)之间的所有内容都被正则表达式引擎视为一个单一标记。因为整个组是一个令牌,所以一旦正则表达式引擎找到该组的匹配项,就不会发生回溯。如果需要回溯,则引擎必须在组之前回溯到正则表达式令牌(在我们的示例中为插入符号)。如果组之前没有令牌,则正则表达式必须在字符串中的下一个位置重试整个正则表达式。请注意,我需要包含“&lt;”在小组中确保原子性。足够接近。

答案 3 :(得分:0)

嗯......有一种方法可以告诉我找到最小的匹配,而且正是通过使用非贪婪的量词。

<bla><blabla>87765.*?</blabla><bla>

我无法想象为什么在使用贪婪量词时你会想要这样做。