具有重复组名的正则表达式
regex with repeated group names
我正在尝试制作一个正则表达式,其中我有一些重复的组名,例如,在下面的示例中,我想找到 ph
、A
和 [=14 的值=] 这样,如果我在 pattern
中替换它们,我将检索 string
。我使用 regex
执行此操作,因为 Python 的默认 re
库不允许重复名称。
pattern = '(?P<ph>.*?) __ (?P<A>.*?) __ (?P<B>.*?) __ \( (?P<ph>.*?) \-> (?P<A>.*?) = (?P<B>.*?) \) \)'
string = 'y = N __ ( A ` y ) __ ( A ` N ) __ ( y = N -> ( A ` y ) = ( A ` N ) ) )'
match = regex.fullmatch(pattern, string)
for k, v in match.groupdict().items():
print(f'{k}: {v}')
然后我检索了预期的输出:
ph: y = N
A: ( A ` y )
B: ( A ` N )
我担心的是这个库似乎有一些问题,或者我没有正确使用它。例如,如果我将 string
替换为:
string = 'BLABLA __ ( A ` y ) __ ( A ` N ) __ ( y = N -> ( A ` y ) = ( A ` N ) ) )'
然后上面的代码为 ph
、A
和 B
提供完全相同的值,忽略 string
开头的 BLABLA
前缀,并且 match
应该是 None
因为没有解决方案。
有什么想法吗?
注意:更准确地说,在我的问题中,我有一对 patterns/strings (p_0, s_0) ... (p_n, s_n)
,我必须在这些对中找到一个有效的匹配项,所以我将它们与 __
连接在一起分隔符,但我也很好奇是否有正确的方法来做到这一点。
由于您要确保前三组与相应的后三组相等,因此您需要对前三组使用 backreferences 而不是使用同名捕获再次分组:
^(?P<ph>.*?) __ (?P<A>.*?) __ (?P<B>.*?) __ \( (?P=ph) \-> (?P=A) = (?P=B) \) \)$
此处,(?P=ph)
、(?P=A)
和 (?P=B)
是 named backreferences 匹配捕获到具有相应名称的组中的相同文本。
^
和 $
锚点在您的代码中不是必需的,因为您使用 regex.fullmatch
方法,但是当您在正则表达式测试器中在线测试您的模式时需要它们。
我正在尝试制作一个正则表达式,其中我有一些重复的组名,例如,在下面的示例中,我想找到 ph
、A
和 [=14 的值=] 这样,如果我在 pattern
中替换它们,我将检索 string
。我使用 regex
执行此操作,因为 Python 的默认 re
库不允许重复名称。
pattern = '(?P<ph>.*?) __ (?P<A>.*?) __ (?P<B>.*?) __ \( (?P<ph>.*?) \-> (?P<A>.*?) = (?P<B>.*?) \) \)'
string = 'y = N __ ( A ` y ) __ ( A ` N ) __ ( y = N -> ( A ` y ) = ( A ` N ) ) )'
match = regex.fullmatch(pattern, string)
for k, v in match.groupdict().items():
print(f'{k}: {v}')
然后我检索了预期的输出:
ph: y = N
A: ( A ` y )
B: ( A ` N )
我担心的是这个库似乎有一些问题,或者我没有正确使用它。例如,如果我将 string
替换为:
string = 'BLABLA __ ( A ` y ) __ ( A ` N ) __ ( y = N -> ( A ` y ) = ( A ` N ) ) )'
然后上面的代码为 ph
、A
和 B
提供完全相同的值,忽略 string
开头的 BLABLA
前缀,并且 match
应该是 None
因为没有解决方案。
有什么想法吗?
注意:更准确地说,在我的问题中,我有一对 patterns/strings (p_0, s_0) ... (p_n, s_n)
,我必须在这些对中找到一个有效的匹配项,所以我将它们与 __
连接在一起分隔符,但我也很好奇是否有正确的方法来做到这一点。
由于您要确保前三组与相应的后三组相等,因此您需要对前三组使用 backreferences 而不是使用同名捕获再次分组:
^(?P<ph>.*?) __ (?P<A>.*?) __ (?P<B>.*?) __ \( (?P=ph) \-> (?P=A) = (?P=B) \) \)$
此处,(?P=ph)
、(?P=A)
和 (?P=B)
是 named backreferences 匹配捕获到具有相应名称的组中的相同文本。
^
和 $
锚点在您的代码中不是必需的,因为您使用 regex.fullmatch
方法,但是当您在正则表达式测试器中在线测试您的模式时需要它们。