我使用python正则表达式库解析一些字符串,目前我发现我的正则表达式太复杂或者我搜索的字符串太长。
以下是挂断的示例:
>>> import re
>>> reg = "(\w+'?\s*)+[-|~]\s*((\d+\.?\d+\$?)|(\$?\d+\.?\d+))"
>>> re.search(reg, "**LOOKING FOR PAYPAL OFFERS ON THESE PAINTED UNCOMMONS**") #Hangs here...
我不确定发生了什么。任何帮助表示赞赏!
编辑:以下是我尝试匹配的示例的链接:Regxr
答案 0 :(得分:4)
代码执行挂起的原因是catastrophic backtracking,因为在量化组(\w+'?\s*)+
内允许正则表达式引擎测试的一个强制性和1个以上可选模式(可以匹配空字符串的模式)很多匹配的路径,很多都需要很长时间才能完成。
我建议以'
或\s
成为强制性的方式展开有问题的群体,并将其包装在可选群组中:
(\w+(?:['\s]+\w+)*)\s*[-~]\s*(\$?\d+(?:\.\d+)?\$?)
^^^^^^^^^^^^^^^^^^^***
请参阅regex demo
在这里,(\w+(?:['\s]+\w+)*)
将匹配1个以上的字符,然后是0 + 1 + '
或空格的序列,后跟1个字的字符。这样,如果出现不匹配的字符串,则模式将变为线性,并且正则表达式引擎会更快地使匹配失败。
其余模式:
\s*[-~]\s*
- 包含0 +空格的-
或~
(\$?\d+(?:\.\d+)?\$?)
- 第2组捕获
\$?
- 1或0 $
个符号\d+
- 1+位数(?:\.\d+)?
- 1或0个零序列:
\.
- 一个点\d+
- 1+位数\$?
- 1或0 $
个符号