Python 正则表达式:选择一个或另一个正则表达式

2 投票
2 回答
669 浏览
提问于 2025-04-18 13:51

我正在尝试创建一个正则表达式,根据输入选择使用一个正则表达式或另一个。下面是我正则表达式的简化版本:

string = '78 east easy street New York NY 11011'
REGEX = r'(?:' +\
            r'(?P<num1>6\d+)' +\
            r'|' +\
            '(?P<num2>7\d+)' +\
        r')'
m = re.match(REGEX, string)

我的结果看起来是这样的:

 78 east easy street New York NY 11011
    Matched: 78
    num1:   None
    num2:   78

我有几个问题: 1. 为什么结果中同时出现了num1和num2?它会选择正则表达式1还是2? 2. 有没有办法让下面这样的正则表达式工作(这在创建复杂的模式匹配时会很有帮助):

REGEX = '(?:' + '(?P<num>6\d+)' +  '|' + '(?P<num1>7\d+)' + ')'

补充:我希望第一个代码片段的输出是选择正确的正则表达式,所以输出中要么是num1,要么是num2。

2 个回答

2

为了补充@Jerry的回答,你可以使用Python的regex模块来实现这个功能。

>>> import regex
>>> s = '78 east easy street New York NY 11011'
>>> m = regex.match(r'(?|(?P<num>6\d+)|(?P<num>7\d+))', s)
>>> m.group('num')
'78'

条件正则表达式中的重复子模式组在这个组里的所有子模式( .. )都有相同的编号。如果条件满足,就使用第一个模式;如果不满足,就使用第二个模式。

文档中提到:

同名的组会有相同的组编号,而不同名的组会有不同的组编号。组编号会在不同的分支中重复使用... 比如(?|(first)|(second))只有一个组1

4

1) 为什么结果中会出现 num1 和 num2?它会选择正则表达式 1 还是 2?

你有两个捕获组,所以结果中会同时出现 num1num2。它并不是“选择”其中一个,而是会找到第一个匹配的部分。无论捕获到的部分是全部、部分还是没有,你都会得到这两个捕获组,因为它们都在整体表达式中。

2) 有没有办法让下面这样的正则表达式工作(这在创建复杂模式匹配时会很有帮助):

    REGEX = '(?:' + '(?P<num>6\d+)' +  '|' + '(?P<num1>7\d+)' + ')'

上面的正则表达式如果你试一下是可以工作的,只是你会得到 numnum1。如果你想让两个组的名字相同,那在 Python 中是不行的。

不过在 C# 中可以做到,因为它的正则表达式实现允许使用相同名字的捕获组。

在 PCRE 以及实现这个正则引擎的语言中(包括 Python 中的 regex 模块,但遗憾的是在当前的 re 模块中不可用),你可以使用“重复子模式组”,语法如下:

(?| ... | ... )

如果你在每个“隔间”中都有一个捕获组,它们会合并成一个组,匹配到的部分会放在一起。

例如:

(?|(?P<num>6\d+)|(?P<num>7\d+))

将返回名为 num 的组,里面包含匹配到的部分。

撰写回答