我正在尝试创建一个功能来捕获以规范形式(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*|-?)
并且它有效。问题是我不理解(?:...)
的两者之间的区别,也不了解创建非捕获组的目的。对我来说,文档也不够清晰。
答案 0 :(得分:2)
考虑一个更简单的例子:
re.compile(r'(?:a|b)*')
简单地匹配a
和b
的(可能为空)字符串。这和
re.compile(r'(a|b)*')
是匹配引擎将使用group
方法捕获匹配的第一个匹配字符。使用非捕获组只是在不需要捕获组时加速匹配(或至少节省内存)的优化。
答案 1 :(得分:2)
您替换的部分中有备用令牌。替代将匹配令牌之前的内容或之后的内容。因为将正则表达式分成像你在这里所做的那样的行不被认为是分组,所以它不仅会尝试匹配同一行之前或之后的行,而且也会匹配之前和之后的行。
分组应该通过在括号中包围该组来完成,但是默认情况下这也会“捕获”该组,这意味着当您调用groups()
时,它将返回匹配作为其中一个组。要指定它不应该,您需要添加?:
。