我在一些Python身上测试,它们都是遇到的问题
如果我使用
a=re.findall(r"""<ul>[\s\S]*?<li><a href="(?P<link>[\s\S]*?)"[\s\S]*?<img src="(?P<img>[\s\S]*?)"[\s\S]*?<br/>[\s\S]*?</li>[\s\S]*?</li>[\s\S]*?</li>[\s\S]*?</ul>""",html)
print a
没事的
但如果我用
^{2}$它会阻止服务器,并一直等待,就像服务器死了一样,我也测试了regexbuddy
第二个代码片段的区别只是代码片段的末尾
任何人都能解释为什么会这样
表达式
[\s\S]*?
可以匹配任何数量的任何内容。在匹配失败的情况下,这可能会导致大量的回溯。如果你对你能匹配的和不能匹配的更具体,那么它将允许匹配更快地失败。在另外,我建议您使用HTML解析器而不是正则表达式。靓汤是一个很好用的图书馆。在
您的正则表达式正在遭受catastrophic backtracking的影响。如果它能找到一个匹配的,那就没问题了,但如果找不到,它就必须在放弃之前尝试无数种可能性。这些
[\s\S]*?
构造中的每一个最终都试图匹配到文档的末尾,它们之间的交互会产生大量无用的工作。在Python不支持atomic groups,但是有一个小技巧可以用来模仿它们:
如果lookahead成功,整个
<UL>
元素被捕捉到组1中,匹配位置重置为元素的开头,然后\1
反向引用将消耗该元素。但是,如果下一个字符不是d
,它会像regex一样,返回并重新处理所有这些[\s\S]*?
结构。在相反,regex引擎直接返回到}之间)并从开始处再次尝试lookahead。它一直这样做,直到找到与lookahead匹配的另一个匹配项,或者到达文档末尾。这样,它将失败(预期结果)大约与您的第一个正则表达式成功的时间相同。在
<UL>
元素的开头,然后向前撞一个位置(因此它在<
和{请注意,我并不是将此技巧作为解决方案,只是试图回答您的问题,即为什么regex似乎挂起。如果我提供了一个解决方案,我会说停止使用},或{});你太依赖了。尽量具体化,例如,不要:
^{pr2}$[\s\S]*?
(或[\s\S]*
,或{…使用:
但即使这样也有严重的问题。你应该认真考虑使用一个HTML解析器来完成这个任务。我也喜欢正则表达式,但你对它们要求太高了。在
相关问题 更多 >
编程相关推荐