Python 正则表达式 - 使用"|"有选择地命名组(正则表达式中的"或")



我使用python-regex将模式与字符串匹配,并面临基于多个模板命名组的问题。

如果简化,这将是一个写作问题;

pattern = r'(?P<one>1)|(?P<one>one)'
string = 'one'
re.match(pattern, string).groupdict()

我想要{'one': 1}{'one': 'one'}作为输出。然而,这引发了错误;

error: redefinition of group name 'one' as group 2; was group 1 at position 15

一个更具体的例子:我有一个字符串列表,每个字符串包含;

  • 前缀类似于"hello">
  • 此人的性别,以及
  • 他/她的生日

像这样;

['hello F 10/Feb', 'hello Jan/12 M', 'hi F Feb 15', ...]

等等

他们似乎有多样性,但所有人都遵循其中一个模板;

  • 前缀+[space]+性别+[space]]+日期+'/'+月份
  • 前缀+[space]+月+'/'+日+[space]]+性别
  • 前缀+空格+性别+空格+月份+空格+天

所以我想使用正则表达式,并使用re.match()将它们包含在字典中。

首先,我列出了用regex编写的模板列表。

template = [
r'((?P<gender>[FM]) (?P<day>d+)/(?P<month>d+))',
r'((?P<month>.+)/(?P<month>d+) (?P<gender>[FM]))',
r'((?P<gender>[FM]) (?P<month>.+)/(?P<day>d))',]

在这里,我删除了问候语部分,因为它从未改变它的位置,并且出于可用性的目的,我想将前缀部分保留为变量prefix

然后我试着用像这样的'|'加入他们

prefix + r'|'.join(template)

使正则表达式形成一个连接字符串。

然而,当我尝试将它与regex匹配时,我遇到了重新定义的错误。


我知道可以做到

for i in template:
re.match(prefix + i, string)

有点像,但如果可能的话,我想把模式字符串保持在一行。

这可能吗?

(我使用Python 3.5.2|Anaconda 4.2.0(64位))

这是可能的,但使用标准的re模块是不可能的。您正在寻找的功能是一个分支重置组,它允许为不同的替换重新定义组。这既可用于编号组,也可用于命名组。要在python中使用它,可以使用PyPi-Regex模块。

通用语法是(?|(.)|(.)),其中两个捕获组都用1编号,因为它们出现在不同的交替中。这同样可以用于命名组,因此您的示例可以写成(?|(?P<one>1)|(?P<one>one))

请参阅regex 101上的演示。

注意:这是使用PCRE模式,PCRE和regex模块之间存在差异,但显示的功能是两者共享的。

最新更新