【问题标题】:regex with repeated group names具有重复组名的正则表达式
【发布时间】:2020-11-26 14:42:00
【问题描述】:

我正在尝试创建一个正则表达式,其中我有一些重复的组名,例如,在下面的示例中,我想找到 phAB 的值,这样如果我替换它们在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 -&gt; ( A ` y ) = ( A ` N ) ) )'

那么上面的代码为phAB提供完全相同的值,忽略string开头的BLABLA前缀,match应该是None没有解决办法。

有什么想法吗?

注意:更准确地说,在我的问题中,我有一对模式/字符串 (p_0, s_0) ... (p_n, s_n),我必须在这些对中找到有效匹配,所以我将它们与 __ 分隔符连接在一起,但我也很好奇是否有一个适当的方法可以做到这一点。

【问题讨论】:

  • “忽略 BLABLA 前缀”是什么意思?你有什么要求? (?P&lt;ph&gt;.*?) 将在此处匹配 BLABLA,因为它可以尽可能少地匹配任何 0 个或多个字符
  • 所以我希望如果您替换 phAB 的值,那么您将准确检索 string,而不是它的子集。我认为这就是 fullmatch 所做的(至少对于 re 库而言)。
  • 什么是subst?无论如何,. 匹配任何字符。如果您不希望它匹配任何字符但某些特定字符,请使用特定模式,不要使用.*?模式要求是什么?我不问你有什么任务。
  • 您的意思是您希望前 3 个组等于相应的接下来的 3 个组吗? ^(?P&lt;ph&gt;.*?) __ (?P&lt;A&gt;.*?) __ (?P&lt;B&gt;.*?) __ \( (?P=ph) \-&gt; (?P=A) = (?P=B) \) \)$?见regex101.com/r/r7IZ77/1
  • 哦,是的,我不知道?P= 反向引用的事情。这正是我的意思。成功了,谢谢!

标签: python regex regex-group python-regex


【解决方案1】:

由于您要确保前三个组等于相应的下三个组,您需要对前三个组使用反向引用,而不是再次使用同名的捕获组:

^(?P<ph>.*?) __ (?P<A>.*?) __ (?P<B>.*?) __ \( (?P=ph) \-> (?P=A) = (?P=B) \) \)$

regex demo

这里,(?P=ph)(?P=A)(?P=B)named backreferences,它们与捕获到具有相应名称的组中的相同文本匹配。

^$ 锚在您的代码中不是必需的,因为您使用了 regex.fullmatch 方法,但是当您在正则表达式测试器中在线测试您的模式时需要它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多