python重问题

2024-04-25 11:54:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一些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

第二个代码片段的区别只是代码片段的末尾

任何人都能解释为什么会这样


Tags: 代码brresrc服务器imghtmllink
2条回答

表达式[\s\S]*?可以匹配任何数量的任何内容。在匹配失败的情况下,这可能会导致大量的回溯。如果你对你能匹配的和不能匹配的更具体,那么它将允许匹配更快地失败。在

另外,我建议您使用HTML解析器而不是正则表达式。靓汤是一个很好用的图书馆。在

您的正则表达式正在遭受catastrophic backtracking的影响。如果它能找到一个匹配的,那就没问题了,但如果找不到,它就必须在放弃之前尝试无数种可能性。这些[\s\S]*?构造中的每一个最终都试图匹配到文档的末尾,它们之间的交互会产生大量无用的工作。在

Python不支持atomic groups,但是有一个小技巧可以用来模仿它们:

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>))\1d""",html)
print a

如果lookahead成功,整个<UL>元素被捕捉到组1中,匹配位置重置为元素的开头,然后\1反向引用将消耗该元素。但是,如果下一个字符不是d,它会像regex一样,返回并重新处理所有这些[\s\S]*?结构。在

相反,regex引擎直接返回到<UL>元素的开头,然后向前撞一个位置(因此它在<和{}之间)并从开始处再次尝试lookahead。它一直这样做,直到找到与lookahead匹配的另一个匹配项,或者到达文档末尾。这样,它将失败(预期结果)大约与您的第一个正则表达式成功的时间相同。在

请注意,我并不是将此技巧作为解决方案,只是试图回答您的问题,即为什么regex似乎挂起。如果我提供了一个解决方案,我会说停止使用[\s\S]*?(或[\s\S]*,或{},或{});你太依赖了。尽量具体化,例如,不要:

^{pr2}$

…使用:

<a href="(?P<link>[^"]*)"[^>]*><img src="(?P<img>[^"]*)"[^>]*>

但即使这样也有严重的问题。你应该认真考虑使用一个HTML解析器来完成这个任务。我也喜欢正则表达式,但你对它们要求太高了。在

相关问题 更多 >