Python 正则表达式:选择一个或另一个正则表达式
我正在尝试创建一个正则表达式,根据输入选择使用一个正则表达式或另一个。下面是我正则表达式的简化版本:
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 个回答
为了补充@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
。
1) 为什么结果中会出现 num1 和 num2?它会选择正则表达式 1 还是 2?
你有两个捕获组,所以结果中会同时出现 num1
和 num2
。它并不是“选择”其中一个,而是会找到第一个匹配的部分。无论捕获到的部分是全部、部分还是没有,你都会得到这两个捕获组,因为它们都在整体表达式中。
2) 有没有办法让下面这样的正则表达式工作(这在创建复杂模式匹配时会很有帮助):
REGEX = '(?:' + '(?P<num>6\d+)' + '|' + '(?P<num1>7\d+)' + ')'
上面的正则表达式如果你试一下是可以工作的,只是你会得到 num
和 num1
。如果你想让两个组的名字相同,那在 Python 中是不行的。
不过在 C# 中可以做到,因为它的正则表达式实现允许使用相同名字的捕获组。
在 PCRE 以及实现这个正则引擎的语言中(包括 Python 中的 regex
模块,但遗憾的是在当前的 re
模块中不可用),你可以使用“重复子模式组”,语法如下:
(?| ... | ... )
如果你在每个“隔间”中都有一个捕获组,它们会合并成一个组,匹配到的部分会放在一起。
例如:
(?|(?P<num>6\d+)|(?P<num>7\d+))
将返回名为 num
的组,里面包含匹配到的部分。