【发布时间】:2016-07-14 20:59:18
【问题描述】:
我有一个正则表达式:
import re
regexp = re.compile(r'^(?P<parts>(?:[\w-]+/?)+)/$')
它匹配foo/bar/baz/ 之类的字符串,并将foo/bar/baz 放在名为parts 的组中(/? 与/$ 组合支持这一点)。
这很好用,直到你匹配一个不以斜杠结尾的字符串。然后,随着您添加到要匹配的字符串中的每个新字符,它会以看似指数的速度变慢。
示例
# This is instant (trailing slash)
regexp.match('this-will-take-no-time-at-all/')
# This is slow
regexp.match('this-takes-about-5-seconds')
# This will not finish
regexp.match('this-probably-will-not-finish-until-the-day-star-turns-black')
我试图理解为什么这个特定的递归问题只发生在/$(斜杠)不在字符串中(即不匹配)时。你能帮我理解下斜杠和非斜杠情况下底层算法的控制流程吗?
注意
我不是在为我想要的模式寻找解决方案。我正在尝试了解具体的正则表达式。
【问题讨论】:
-
将您的模式和示例粘贴到regex101.com,切换到调试器并取消选中内部优化 - 然后看看 :) 引擎尝试使用两种 +-重复的所有可能组合,试图以某种方式找到匹配项。
-
@SebastianProske 感谢您的建议,但 regex101.com 只是在调试器中立即告诉我该模式根本不匹配,这意味着他们的引擎(JS?)没有使用相同的像 Python 一样的算法(永远不会完成)。
-
又是一个类似
(A+)+的模式。导致问题的原因是灾难性的回溯。我猜你需要^(?P<parts>[\w-]+(?:/[\w-]+)*)/$ -
@orokusaki 你应该turn off the internal optimizations 看看会发生什么。
-
类似情况:stackoverflow.com/questions/22650098/… 有几个很好的解释。
标签: python regex regex-greedy