在 Python 正则表达式中,
re.compile("x"*50000)
给我 OverflowError: 超出正则表达式代码大小限制
但下面一个没有出现任何错误,但它达到了 100% CPU,并且在我的 PC 上花费了 1 分钟
>>> re.compile(".*?.*?.*?.*?.*?.*?.*?.*?.*?.*?"*50000)
<_sre.SRE_Pattern object at 0x03FB0020>
这正常吗?
我应该假设 ".*?.*?.*?.*?.*?.*?.*?.*?.*?.*?"*50000
更短比 "x"*50000
?
在 Python 2.6、Win32 上测试
更新 1:
看起来 ".*?.*?.*?.*?.*?.*?.*?.*?.*?.*?"*50000
可以减少到 .*?
那么,这个怎么样?
re.compile(".*?x"*50000)
它确实编译,如果那个也可以减少到 ".*?x"
,它应该匹配字符串 "abcx"
或 "x "
单独,但不匹配。
那么,我是不是漏掉了什么?
更新 2:
我的意思是不知道正则表达式源字符串的最大限制,我想知道溢出处理程序捕获的 "x"*50000
的一些原因/概念,但不是 "。 *?x"*50000
。
这对我来说没有意义,这就是原因。
溢出检查时缺少什么东西或者它很好还是它真的溢出了什么东西?
任何提示/意见将不胜感激。
最佳答案
区别在于 ".*?.*?.*?.*?.*?.*?.*?.*?.*?.*?"*50000
可以是减少到 ".*?"
,而 "x"*50000
必须在 FSM(或正则表达式引擎使用的类似结构)中生成 50000 个节点。
编辑: 好吧,我错了。这不是那么聪明。 "x"*50000
失败而 ".*?x"*50000
失败的原因是一个“代码项”的大小有限制. "x"*50000
将生成一个长项,".*?x"*50000
将生成许多小项。如果您可以在不改变正则表达式的含义的情况下以某种方式拆分字符串文字,它会起作用,但我想不出一种方法来做到这一点。
关于Python 的正则表达式源字符串长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1998261/