Я построил такое регулярное выражение, следуя инструкциям
#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
который не имеет пробелов.
Как могут генерироваться дополнительные пробелы?
re.findall (pattern, string, flags = 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')
Надеюсь, поможет!! Пожалуйста, не стесняйтесь спрашивать, есть ли у вас какие-либо сомнения.
Как отмечает 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']]
''
- это пустая строка, а неNone
..findall()
есть девять групп. Если вам не нужны все эти группы, измените их на группы без захвата -(?:...)
вместо(...)
. Или просто уберите круглые скобки, если они на самом деле ни для чего не нужны.