Регулярное выражение по поиску номера телефона в строке

Нашел на просторах интернета регулярное выражение по поиску российских номеров телефона:

^((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 шт):

Автор решения: gil9red

Символ ^ в начале означает, что строка по шаблону будет идти включая первым символ, а символ $ в конце означает, что включительно до последнего, т.е. регулярка ищет по полному совпадению строки

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 ']
→ Ссылка
Автор решения: SergFSM

можно попробовать так, правда если в строке кроме номеров телефонов есть посторонние цифры, то код в некоторых случаях может работать не совсем корректно:

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', '']
→ Ссылка