免责声明:我不是正则表达专家。
我正在使用Python re模块在许多htm文件上执行正则表达式匹配。其中一种模式是这样的:
<bla><blabla>87765.*</blabla><bla>
我遇到的问题是,不是找到所有(比如说)五次出现的模式,而是只找到一个。因为它使用第一次出现的<bla><blabla>87765
部分和页面中最后一次出现的</blabla><bla>
部分将所有出现次数合并为一次。
有没有办法告诉重新找到最小的匹配?
答案 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>
我无法想象为什么在使用贪婪量词时你会想要这样做。