Регулярное выражение по поиску номера телефона в строке
Нашел на просторах интернета регулярное выражение по поиску российских номеров телефона:
^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$
Автором сказано, что пропускает следующие номера:
Зеленый свет для:
+79261234567
89261234567
79261234567
+7 926 123 45 67
8(926)123-45-67
123-45-67
9261234567
79261234567
(495)1234567
(495) 123 45 67
89261234567
8-926-123-45-67
8 927 1234 234
8 927 12 12 888
8 927 12 555 12
8 927 123 8 123
Но когда проверяю, метод re.findall() возвращает пустой список:
string = '89261234567 Nomer Nomer'
print(re.findall(r"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$", string))
output: []
И не могу понять, что не так. Может я что-то упускаю?
Ответы (2 шт):
Символ ^ в начале означает, что строка по шаблону будет идти включая первым символ, а символ $ в конце означает, что включительно до последнего, т.е. регулярка ищет по полному совпадению строки
r"^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$"
#^^^ ^^^
Вам нужно просто убрать эти символы.
Кст, findall при поиске выделяет в результате группы захваченных символов (круглые скобки), поэтому результат будет несколько неожиданный (для вашего примера [('8', '8', '926')]).
Решением будет использовать finditer:
string = '89261234567 Nomer Nomer'
items = [
m.group()
for m in re.finditer(r"((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}", string)
]
print(items)
# ['89261234567 ']
Или сделать группы игнорируемыми, для этого нужно перед каждой круглой скобкой (но не экранируемой!) добавить ?::
string = '89261234567 Nomer Nomer'
print(re.findall(r"(?:(?:8|\+7)[\- ]?)?(?:\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}", string))
# ^^^^^^ ^^^
# ['89261234567 ']
можно попробовать так, правда если в строке кроме номеров телефонов есть посторонние цифры, то код в некоторых случаях может работать не совсем корректно:
from re import split,search,sub
string='+8 (926)1234567 Nomer 7(495)123-45-67 Nomer 123-45-67 1,2315'
def f(x):
s = search(r'[7|8]\d{10}|[^0]\d{6}',sub(r'[^\d]','',x))
return s and s[0] or ''
print([f(i) for i in split(r'[^\d\s\+\(\)-]+',string)])
#
['89261234567', '74951234567', '1234567', '']