据我正在阅读的在线教程指出:
与问号的可选匹配
“有时,您只需要可选地匹配一个模式。即,正则表达式应该找到匹配项,无论是否存在该文本位。?字符将其前面的组标记为的可选部分例如,在交互式外壳程序中输入以下内容:“
>>> batRegex = re.compile(r'Bat(wo)?man')
>>> mo1 = batRegex.search('The Adventures of Batman')
>>> mo1.group()
'Batman'
我的问题:
我正在尝试以123-456-7890
(无国家代码)或(111)-123-456-7890
(有国家代码)的形式查找匹配的电话号码。
这是我的python正则表达式代码,用于返回匹配的电话号码列表:
phone_num_regex = re.compile(r'(\(\d{3}\)-)?\d{3}-\d{3}-\d{4}')
phone_num_list = phone_num_regex.findall('800-420-7240 (933)-415-863-9900 415-863-9950')
但是,我获得的phone_num_list是['', '(933)-', '']
,而不是我想要的['800-420-7240, '(933)-415-863-9900', '415-863-9950']
。
我可以知道我的代码有什么问题吗?我猜这与“?”有关(可选匹配项)
答案 0 :(得分:1)
您要将可选部分包含在捕获组中,这意味着re.findall
所给的就是这些组。
如果您改用非捕获组,则不会发生这种情况。
re.compile(r'(?:\(\d{3}\)-)?\d{3}-\d{3}-\d{4}')
来自the docs:
(...)
匹配括号内的任何正则表达式,并指示组的开始和结束;可以在执行匹配后检索组的内容,并且以后可以在字符串中使用\number
特殊序列进行匹配,如下所述。要匹配文字'('
或')'
,请使用\(
或\)
,或将它们括在字符类中:[(]
,[)]
。 / p>
(?:...)
非捕获版本的常规括号。匹配括号内的任何正则表达式,但执行匹配后无法检索该组匹配的子字符串,也无法在模式的稍后引用。
re.findall(pattern, string, flags=0)
返回字符串中模式的所有非重叠匹配项,作为字符串列表。从左到右扫描该字符串,并以找到的顺序返回匹配项。 如果该模式中存在一个或多个组,请返回组列表;如果模式包含多个组,则这将是一个元组列表。空匹配项包含在结果中。
(重点是我的)