re.findall产生意外的额外空间

时间:2018-08-23 04:03:33

标签: python regex

我按照指示构建了这样的正则表达式

#Create phone regex
phoneRegex = re.compile(r'''( 
    (\d{3}|\(\d{3}\))?  # area code
    (\s|-|\.)?  # separator
    (\d{3})  # first 3 digits
    (\s|-|\.) # separator
    (\d{4})  # last 4 digits
    (\s*(ext|x|ext.)\s*(\d{2,5}))?  # extension
    )''', re.VERBOSE)

我测试了

In [91]: text 
Out[91]: '800-420-7240 415-863-9900 415-863-9950'
In [92]: phoneRegex.findall(text)
Out[92]: 
[('800-420-7240', '800', '-', '420', '-', '7240', '', '', ''),
 ('415-863-9900', '415', '-', '863', '-', '9900', '', '', ''),
 ('415-863-9950', '415', '-', '863', '-', '9950', '', '', '')]

每个组的末尾有三个None,尤其是415-863-9950的最后一个无空格。

如何产生多余的空间?

2 个答案:

答案 0 :(得分:1)

就像jasenharper在评论中指出的那样,空字符串的来源起源于空捕获组。摆脱它们的最简单方法是在应用正则表达式后清理列表:

s = phoneRegex.findall(text)
s = [('800-420-7240', '800', '-', '420', '-', '7240', '', '', ''),
 ('415-863-9900', '415', '-', '863', '-', '9900', '', '', ''),
 ('415-863-9950', '415', '-', '863', '-', '9950', '', '', '')]

newS = []
for e in s:
    sl = list(filter(lambda x: x != "",e))
    newS.append(sl)
print(newS) # [['800-420-7240', '800', '-', '420', '-', '7240'], ['415-863-9900', '415', '-', '863', '-', '9900'], ['415-863-9950', '415', '-', '863', '-', '9950']]

答案 1 :(得分:1)

  

re.findall (样式,字符串,标志= 0)

     

以字符串列表形式返回字符串中所有不重复的模式匹配项。字符串从左到右扫描,并且匹配项是   以找到的顺序返回。如果一个或多个组存在于   模式,返回组列表;这将是一个元组列表,如果   模式有多个组。 空匹配包含在中   结果

https://docs.python.org/2/library/re.html#re.findall

在正则表达式中,您有一个可选组。即:

(\s*(ext|x|ext.)\s*(\d{2,5}))?

?表示该组是可选的,因此,findAll()为每个不匹配的组返回None。当然,您可以通过在组之前添加?:来将组标记为未捕获,但是,如果这样做,将无法捕获诸如800-420-7240 ext 1112 415-863-9900 415-863-9950(根据最后一个组,捕获ext)。 [如果我对上一条陈述有误,请纠正我]

但是,您可以删除None值,并使用小的解决方法仅返回有效的组。

import re

phoneRegex = re.compile(r'''( 
    (\d{3}|\(\d{3}\))?  # area code
    (\s|-|\.)?  # separator
    (\d{3})  # first 3 digits
    (\s|-|\.) # separator
    (\d{4})  # last 4 digits
    (\s*(ext|x|ext.)\s*(\d{2,5}))?  # extension
    )''', re.VERBOSE)

matches = phoneRegex.findall('800-420-7240 ext 1112 415-863-9900 415-863-9950')
# matches = phoneRegex.findall('800-420-7240 415-863-9900 415-863-9950')

for i in matches:
    print filter(None, i)

这将输出为:

('800-420-7240 ext 1112', '800', '-', '420', '-', '7240', ' ext 1112', 'ext', '1112')
('415-863-9900', '415', '-', '863', '-', '9900')
('415-863-9950', '415', '-', '863', '-', '9950')

希望有帮助!!请随时询问您是否有任何疑问。