【问题标题】:Multiple capturing groups within non-capturing group using Python regexes使用 Python 正则表达式的非捕获组中的多个捕获组
【发布时间】:2020-10-11 00:01:40
【问题描述】:

我有以下代码在一个非捕获组中使用多个捕获组:

>>> regex = r'(?:a ([ac]+)|b ([bd]+))'
>>> re.match(regex, 'a caca').groups()
('caca', None)
>>> re.match(regex, 'b bdbd').groups()
(None, 'bdbd')

如何更改代码以输出('caca')('bdbd')

【问题讨论】:

  • 使用 PyPi 正则表达式,您可能会得到 ('caca',)('bdbd',)
  • 在什么条件下?无法使用 PyPi 正则表达式 v2020.6.8 生成。
  • r'(?|a ([ac]+)|b ([bd]+))'
  • 我发布了an answer below,因为您似乎对此感兴趣。我真的相信 Python 应该内置 regex 模块,它比re 在复杂的模式匹配或处理大文本方面更快、更稳定、更强大,它必须是我的默认安装包的一部分意见。

标签: python regex capturing-group


【解决方案1】:

你很接近。

要始终作为组 1 获取捕获,可以使用先行进行匹配,然后使用单独的捕获组进行捕获:

(?:a (?=[ac]+)|b (?=[bd]+))(.*)

Demo

或者在 Python3 中:

>>> regex=r'(?:a (?=[ac]+)|b (?=[bd]+))(.*)'
>>> (?:a (?=[ac]+)|b (?=[bd]+))(.*)
>>> re.match(regex, 'a caca').groups()
('caca',)
>>> re.match(regex, 'b bdbd').groups()
('bdbd',)

【讨论】:

  • 警告:您的正则表达式也在捕获下一个字符(由于 .* )
  • 可以添加一个字符类或额外的正则表达式来解决这个问题。 OP 没有说明他到底在寻找什么……
  • 对,我试图找到一个解决方案来准确覆盖他的比赛,但这不是正确的道路。
【解决方案2】:

另一种选择是在没有捕获组的情况下使用lookbehind 获取匹配项:

(?<=a )[ac]+|(?<=b )[bd]+

Regex demo

例如

import re

pattern = r'(?<=a )[ac]+|(?<=b )[bd]+'
print (re.search(pattern, 'a caca').group())
print (re.search(pattern, 'b bdbd').group())

输出

caca
bdbd

【讨论】:

  • 是的,但是,如果您使用re,后向模式应该匹配相同长度的字符串。同样,使用 PyPi 正则表达式,它将变得更具可扩展性,因为 regex 的后向模式可以匹配任意长度的字符串。
  • 是的,它没有那么灵活。
【解决方案3】:

您可以使用 branch reset groupPyPi regex module:

Alternatives 在分支重置组内共享相同的捕获组。语法是(?|regex),其中(?| 打开组,regex 是任何正则表达式。如果您在分支重置组中不使用任何交替或捕获组,则其特殊功能不会发挥作用。然后它充当non-capturing group

正则表达式看起来像

(?|a ([ac]+)|b ([bd]+))

请参阅regex demo。见Python 3 demo

import regex
rx = r'(?|a ([ac]+)|b ([bd]+))'
print (regex.search(rx, 'a caca').groups()) # => ('caca',)
print (regex.search(rx, 'b bdbd').groups()) # => ('bdbd',)

【讨论】:

    【解决方案4】:

    反过来看问题:

    ((?:a [ac]+)|(?:b [bd]+))
    ^ ^         ^ ^
    | |         | other exact match
    | |         OR
    | not capturing for exact match
    capture everything
    

    更简单的外观:https://regex101.com/r/e3bK2B/1/

    【讨论】:

    • 当我尝试它时,它捕获了整个a caca; OP 只想捕获 caca 部分。
    • 谢谢。享受解释。但@alaniwi 是对的。
    • 对不起,我试图找到另一个解决方案,但没有找到任何解决方案。
    猜你喜欢
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多