我使用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模块之间存在差异,但显示的功能是两者共享的。