【问题标题】:Purpose of (?: ... ) in python regex [duplicate]python 正则表达式中 (?: ... ) 的目的 [重复]
【发布时间】:2017-09-30 20:38:08
【问题描述】:

我正在尝试创建一个函数来捕获以规范形式 (XXX)XXX-XXX 或 XXX-XXX-XXXX 以及附加条件编写的电话号码。这是我的方法

def parse_phone2(s):

    phone_number = re.compile(r'''^\s*\(?       # Begining of string, Ignore leading spaces
                                  ([0-9]{3})    # Area code
                                  \)?\s*|-?     # Match 0 or 1 ')' followed by 0 or more spaces or match a single hyphen
                                  ([0-9]{3})    # Three digit
                                  -?            # hyphen
                                  ([0-9]{4})    # four digits
                                  \s*$          # End of string. ignore trailing spaces''', re.VERBOSE)
    try:
        return (phone_number.match(s).groups())
    except AttributeError as e:
        raise ValueError

我在这个测试用例' (404) 555-1212 ' 失败了,但SO 的另一个问题建议我用(?:\)?\s*|-?) 替换\)?\s*|-? 并且它有效。问题是我不了解两者之间的区别,也不了解(?:...) 的目的,而不是创建非捕获组。文档对我来说也不够清楚。

https://docs.python.org/3/library/re.html

【问题讨论】:

  • (?:...) 可用于构造正则表达式,但与普通括号不同,它不会创建捕获组。
  • 问号字符 ? 匹配一次或零次;您可以将其视为将某些内容标记为可选。例如,home-?brew 匹配 homebrew 或 home-brew。
  • @FadySaad 这不是我的问题。我在问为什么当我使用(?:\)?\s*|-?) 而不是\)?\s*|-?时我的函数通过了

标签: python regex python-3.x


【解决方案1】:

考虑一个更简单的例子:

re.compile(r'(?:a|b)*')

只匹配as 和bs 的(可能为空的)字符串。这和

之间的唯一区别
re.compile(r'(a|b)*')

是匹配引擎将捕获匹配的第一个字符以使用group 方法进行检索。使用非捕获组只是在不需要捕获组时加速匹配(或至少节省内存)的优化。

【讨论】:

    【解决方案2】:

    您替换的部分中有一个备用令牌。 Alternate 将匹配令牌之前的内容或之后的内容。而且由于像您在此处所做的那样将正则表达式分成几行不被视为分组,因此它不仅会尝试匹配同一行之前或之后的内容,还会尝试匹配之前和之后的行。

    应该通过将组括在括号中来完成分组,但默认情况下,这也会“捕获”组,这意味着当您调用 groups() 时,它将作为组之一返回匹配项。要指定它不应该,您需要添加?:

    【讨论】:

      猜你喜欢
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 2022-11-15
      • 2016-04-22
      • 2016-11-16
      • 1970-01-01
      • 2013-05-19
      • 2012-07-13
      相关资源
      最近更新 更多