regex Python中所有格量词的替代方法

sqxo8psd  于 2023-10-22  发布在  Python
关注(0)|答案(3)|浏览(111)

我试图匹配字符串Article后面跟着一个数字(单个或多个数字)的所有占位符,这些数字后面是 not,后面是一个开括号。在Sublime Text中,我使用以下正则表达式:

Article\s[0-9]++(?!\()

搜索以下字符串:

Article 29
Article 30(1)

它不匹配Article 30(1)(正如我所期望的那样),而是Article 29Article 1
当试图在Python(3)中使用

import re
article_list = re.findall(r'Article\s[0-9]++(?!\()', "Article 30(1)")

我得到一个下面的错误,因为我使用了一个Python正则表达式不支持的(嵌套的)所有格量词。有没有办法在Python中匹配我想要(不想要)的东西?

qlckcl4x

qlckcl4x1#

您还可以使用(?=(...))\1解决方案围绕您想要匹配的内容模拟原子组(?>...)

(?=(Article\s[0-9]+))\1(?!\()
  • (lookahead的行为自然就像一个原子组,你所需要的只是一个捕获和一个反向引用)*
k0pti3hp

k0pti3hp2#

Python 3.11更新

现在支持所有格量词和原子组。参见Python 3.11中的新功能:
正则表达式现在支持原子分组((?>...))和所有格量词(*+++?+{m,n}+)。(作者:Jeffrey C。雅各布斯和Serhiy Storchaka在bpo-433030
这意味着,re.findall(r'Article\s[0-9]++(?!\()', "Article 30(1)")现在应该可以按预期工作。

附加参考资料

在这里,在[0-9]++(?!\()中,数字将被匹配和消费,并且在使用[0-9]++消费的最后一个数字之后,将只检查 * 一次 * 负前瞻,如果在该数字之后没有(,则正则表达式匹配将失败,并且不会返回匹配。如果你使用[0-9]+(?!\(),正则表达式引擎会在匹配最后一个数字时回溯,发现后面没有(,它会将搜索索引重新定位在与[0-9]+匹配的最后一个数字之前,并-错误地确认最后一个数字不是(字符-将返回一个截断的匹配数字。

遗留答案

Python re不支持所有格量词。您可以考虑使用Python PyPi regex module来代替,它支持这种类型的量词。或者使用以下变通方法。
您需要在lookahead中添加一个数字:

Article\s[0-9]+(?![(0-9])
                    ^^^

请参见this regex demo
或者,使用单词边界:

Article\s[0-9]+\b(?!\()
                ^

参见this regex demo

m0rkklqb

m0rkklqb3#

只是工作区的附加信息:
从Python 3.11开始,re模块支持原子分组和所有格量词,参见https://docs.python.org/3.11/whatsnew/3.11.html#re和https://github.com/python/cpython/issues/34627

相关问题