【问题标题】:OR'ed backreferences in regular expressions正则表达式中的 OR'ed 反向引用
【发布时间】:2013-03-02 20:56:30
【问题描述】:

谁能解释一下这个正则表达式应该如何工作:

^(a)|\1$

?

我将其解释为:

*1。字符串的开头,

接着是:

*2。要么:

*2a。 a,

或:

*2b。之前匹配的(a) 组,

接着是:

*3。字符串结束

但是,2b 是不可能的,因为如果选择 2b 而不是 2a,则没有先前匹配的 (a) 组。所以,解释等价于:

*1。字符串的开头,

接着是:

*2。 a,

接着是:

*3。字符串结束

换句话说,该正则表达式等同于:^a$(也可以说 OR'ed 反向引用是无意义的。)

但是,在 Python 中,我得到:

>>> import re

>>> re.findall(r'^a$', r'aa')
[] # as expected

>>> re.findall(r'^(a)|\1$', r'a')
['a'] # as expected

>>> re.findall(r'^(a)|\1$', r'aa')
['a'] # NOT as expected

aa 怎么可能匹配 ^(a)|\1$?

【问题讨论】:

  • 恐怕^(a)|\1$ 的意思是(?:^(a))|(?:\1$),而不是^(?:(a)|\1)$。行为完全一致。
  • 一般来说,如果我发现我的正则表达式变得如此复杂,我会做其他事情。你想用这个正则表达式完成什么?它不是适合所有工作的工具。
  • @Jan:是的,你是对的。我被运算符优先级抓住了......谢谢。
  • @jpmc26:“告诉我们你需要什么,我们会解释你为什么不需要它。”
  • @user1387866 我想。我只是看到大量与使用正则表达式进行反向引用相关的问题,这表明它的使用非常复杂。它很复杂的事实向我表明,可能有更好的方法来处理这些情况,即使你让它工作,由于复杂性,它也很难维护。因此我为什么避免它,以及为什么我认为考虑其他途径可能有用。

标签: python regex backreference


【解决方案1】:

这其实是一个正则表达式代码不可达的情况:

原则上,如果且仅当行首的单个 a 已经被匹配。但是,由于在行首匹配单个 a 意味着匹配已经完成,因此永远不会到达正则表达式的第二部分,而只会返回第一个 a。

我猜你有一个更复杂的组,而不仅仅是“a”,所以这里有一个匹配短语a,第二个a(可选),然后是行尾:@ 987654328@

这意味着“在行的开头匹配a,然后允许另一个foo(如果它在那里),然后是字符串的结尾,其中a可以是任何正则表达式模式。如果a真的是只有字母“a”,然后^aa?$ 是一个更简单的替代方案。

如果您只想匹配以a 开头或结尾的任何整行,则^(a.*|.*a)$ 可以工作,或者^(a[^\n]*|[^\n]*a)$ 如果使用单行模式,则简化为^(a.*?|.*?a)$ 用于支持@ 的正则表达式风格987654337@ 运营商。不幸的是,在这种情况下,a 的模式必须写在整个模式的开头和结尾,因为反向引用不会起到作用。如果a 是带有| 运算符的模式,则将其括在括号中,如^((a).*|.*(a))$。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 2018-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多