Python正则表达式中允许的最大重复次数是多少?

12

在 Python 2.7 和 3 中,以下代码可以运行:

>>> re.search(r"a{1,9999}", 'aaa')
<_sre.SRE_Match object at 0x1f5d100>

但是这会导致一个错误:

>>> re.search(r"a{1,99999}", 'aaa')
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "/usr/lib/python2.7/re.py", line 142, in search
   return _compile(pattern, flags).search(string)
   File "/usr/lib/python2.7/re.py", line 240, in _compile
   p = sre_compile.compile(pattern, flags)
   File "/usr/lib/python2.7/sre_compile.py", line 523, in compile
   groupindex, indexgroup
RuntimeError: invalid SRE code

看起来有一个重复次数的上限。这是正则表达式规范的一部分,还是Python特定的限制?如果是Python特定的,实际数字是否有记录,并且在不同的实现之间是否有所不同?

1个回答

14

通过快速手动二分查找,发现答案是65535:

>>> re.search(r"a{1,65535}", 'aaa')
<_sre.SRE_Match object at 0x2a9a68>
>>> 
>>> re.search(r"a{1,65536}", 'aaa')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/re.py", line 142, in search
    return _compile(pattern, flags).search(string)
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/re.py", line 240, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/sre_compile.py", line 523, in compile
    groupindex, indexgroup
OverflowError: regular expression code size limit exceeded

这里讨论了这个问题:

限制是一种实现细节。该模式被编译成代码,然后解释执行,代码通常为16位,即0..65535的范围,但它使用65535表示没有限制,并且如果您实际写入65535,则不会发出警告。

并且

量词符使用65535表示没有上限,因此".{0,65535}"等同于 ".*"。


感谢下面评论区的作者指出了更多内容:

  • CPython在_sre.c中实现了这个限制。 (@LukasGraf)
  • sre_constants.py中有一个常量MAXREPEAT保存了这个最大重复值:

    >>> import sre_constants
    >>> 
    >>> sre_constants.MAXREPEAT
    65535
    

    (@MarkkuK.和@hcwhsa)


1
如果你想在你的回答中指出这一点:对于CPython,这个限制是在_sre.c中实现的。 - Lukas Graf
3
此外,如果您查看sre_constants.py文件,您会发现 MAXREPEAT = 65535 - Markku K.
1
可以使用以下代码找到限制:import sre_constants;print sre_constants.MAXREPEAT - Ashwini Chaudhary
谢谢,我已经将这个添加到答案中了。 - arshajii
2
请注意,sre_constants.MAXREPEAT在非CPython实现中不一定是限制。在PyPy 2.0.0-beta1Jython 2.5.1+IronPython 2.9.9a0上测试len(re.search(r"a{1,999999}", "a"*(2*10**6)).group()) == 999999成功。尽管pypyjython都有sre_constants.MAXREPEAT==65535,但这个方法仍然有效。 - DSM
@DSM 是的,我相信即使在CPython中,“MAXREPEAT”只是一个信息常量(供开发人员查询),但限制实际上是在_sre.c中实施的,并且可能还取决于平台。 - Lukas Graf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接