python正则表达式中(?:...)的目的

时间:2017-09-30 20:38:08

标签: python regex python-3.x

我正在尝试创建一个功能来捕获以规范形式(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

2 个答案:

答案 0 :(得分:2)

考虑一个更简单的例子:

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

简单地匹配ab的(可能为空)字符串。这和

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

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

答案 1 :(得分:2)

您替换的部分中有备用令牌。替代将匹配令牌之前的内容或之后的内容。因为将正则表达式分成像你在这里所做的那样的行不被认为是分组,所以它不仅会尝试匹配同一行之前或之后的行,而且也会匹配之前和之后的行。

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