Как проверить номера телефонов с помощью регулярного выражения

Я пытаюсь собрать комплексное регулярное выражение для проверки телефонных номеров. В идеале он должен обрабатывать международные форматы, но он должен обрабатывать американские форматы, включая следующие:

  • 1-234-567-8901
  • 1-234-567-8901 x1234
  • 1-234-567-8901 ext1234
  • 1 (234) 567-8901
  • 1.234.567.8901
  • 1/234/567/8901
  • 12345678901

Я отвечу своей текущей попыткой, но я надеюсь, что у кого-то есть что-то получше и / или более элегантно.


person Community    schedule 23.09.2008    source источник
comment
Этот ответ был добавлен в Часто задаваемые вопросы о регулярных выражениях при переполнении стека в разделе Общие задачи проверки.   -  person aliteralmind    schedule 10.04.2014


Ответы (41)


Лучший вариант ... просто удалите все нецифровые символы при вводе (кроме знаков 'x' и ведущих '+'), заботясь о британской тенденции писать числа в нестандартной форме +44 (0) ..., когда их просят использовать международный префикс (в этом конкретном случае вы должны полностью отказаться от (0)).

Тогда вы получите такие значения, как:

 12345678901
 12345678901x1234
 345678901x1234
 12344678901
 12345678901
 12345678901
 12345678901
 +4112345678
 +441234567890

Затем, когда вы отображаете, переформатируйте, как вам нравится. например

  1 (234) 567-8901
  1 (234) 567-8901 x1234
person Community    schedule 23.09.2008
comment
Код форматирования будет пустой тратой времени, если числам разрешено поступать из-за пределов США. - person Daniel Earwicker; 21.07.2009
comment
@Earwicker - согласился, что форматирование (при работе с международными #) должно быть достаточно умным, чтобы обрабатывать различные форматы ... например. (0123) 456 7890 или +1 234 567-89-01. В зависимости от того, насколько сложно вы хотите получить, это должно быть что-то, что можно вычислить на основе количества цифр и того, каковы первые несколько цифр. - person scunliffe; 21.07.2009
comment
Это хорошо и все такое, но не проверяет, что было введено на самом деле телефонным номером. Например, что, если пользователь не вводит необходимые 10 цифр? Это должно сочетаться с хорошей проверкой регулярного выражения. - person Hugh Jeffner; 29.07.2010
comment
string.replace ([^ \ d +! x],) - person Joel McBeth; 06.12.2010
comment
jcmcbeth, почему часть !x? Кажется, этого достаточно: [^\d+] rubular.com/r/aj32fRSSGK - person Danilo Bargen; 29.01.2011
comment
@danilo -! x предназначен для предотвращения удаления любого символа x, чтобы можно было отделить расширения. - person cdeszaq; 28.02.2011
comment
Учитывая, что вопрос был о валидации - это действительно плохой ответ. - person PlexQ; 30.03.2012
comment
@PlexQ Я не согласен. Исходная проблема заключается в попытке обработать проверку номера телефона, потому что он пытался обработать все возможные параметры форматирования. Вместо того, чтобы пытаться решить все это, возьмите входные данные и предварительно удалите из них весь мусор форматирования, пока у вас не будет только число. Это решает 2 проблемы: теперь легко проверить результат, и теперь вы можете убедиться, что значения, отображаемые для отображения, могут быть отформатированы единообразно. Первый комментарий к этому ответу о перчатках Complicator - хорошее прочтение ... иногда ответ на проблему состоит в том, чтобы подойти к ней по-другому. - person scunliffe; 31.03.2012
comment
Для других, которые могут использовать вышеуказанный [^\d+!x] - восклицательный знак не нужен. Просто используйте [^\d+x]. См. stackoverflow.com/questions/10340336/. - person Dan Nissenbaum; 27.04.2012
comment
@Raymond, вы можете использовать $justDigitsOrPlusOrX = preg_replace("/[^\d+x]/", "", $phoneNum);, чтобы удалить все символы, которые вам не нужны ... затем проверьте оставшиеся (при необходимости) - person scunliffe; 04.07.2012
comment
Это прекрасно работает, за исключением чисел типа 1-800-CALL-NOW? - person Swanand; 15.02.2013
comment
@Swan и я полагаю, что в этих сценариях, если это то, что вы действительно хотели, вы могли бы включить умный перевод, который преобразовывал бы буквы в соответствующие числа ... но я думаю, что это очень особенный угловой случай по сравнению с тем, что нужно большинству людей. ;-) - person scunliffe; 15.02.2013
comment
Улучшение Regex выше: /[^\d+x]|x(?=[^x]*x)/gi Предотвращает множественные x (использует последний x в строке) - person Albert Bori; 14.05.2013
comment
Это хорошо, но не отвечает на поставленный вопрос, в котором явно запрашивается решение RegEx. - person Kehlan Krumme; 09.08.2013
comment
@nashwan, вы читали статью, указанную в первом комментарии, добавленном Николасом Трандемом. Плакат с исходным вопросом? Иногда (как вы можете видеть, как проголосовало сообщество), даже если есть решение использовать регулярное выражение из 261 символа, которое обрабатывает множество сценариев ... попытка атаковать проблему другим способом - это на самом деле ответ, который вы хотите. Обратите внимание, что ответ Дэйва Кирби также предлагает не использовать строгое регулярное выражение ... также набирает (ATM 79 голосов) - person scunliffe; 28.08.2013
comment
@Swanand Это мило, когда люди объясняют вещи в буквенных обозначениях, которые есть на большинстве телефонных клавиатур, но это не поощряется стандартами. tools.ietf.org/html/rfc3966#section-5.1.2 - person awhie29urh2; 17.10.2013
comment
Вы не можете просто разрешить что-либо, а затем удалить то, что вам не нужно, если вы планируете форматировать позже. Вам нужно что-то, что вы можете отформатировать позже. - person Jack Holt; 26.11.2013
comment
Я должен уточнить, что я сохраню чистое значение и буду украшать его только по мере необходимости для отображения позже. - person scunliffe; 26.11.2013
comment
Вам также нужно быть осторожным, когда вам предлагается число, начинающееся с +44 (0). Это очень распространенный формат в Великобритании, и вы, вероятно, захотите сопоставить его с +44 (т.е. удалить (0)). - person alastair; 01.04.2014
comment
Да, проверка или форматирование телефонных номеров - не лучшая идея. Ниже приведены действительные номера телефонов в Германии: +49 (0) 89 12345, +49 (0) 6221 1234. Если вы находитесь в Германии, набирайте их как 089 12345 или 06221 1234, но, например, В Швейцарии это будет 0049 89 12345 или 0049 6221 1234. Это похоже на случай Великобритании, но наши коды городов не имеют фиксированной длины. Если у вас нет списка, вы не сможете правильно отформатировать числа. - person uliwitness; 01.04.2014
comment
Как, черт возьми, этот ответ получил столько голосов? Это ничего не подтверждает. Что еще хуже, все остальные вопросы о проверке номера телефона ссылаются на этот ... - person jlars62; 19.06.2014
comment
@ jlars62 он может не проверять номер телефона, но он предлагает альтернативное решение, которое более надежно, чем попытки угадать, действителен ли данный номер телефона, учитывая, что идея действительного значительно отличается в разных странах. ИМО, это хорошее решение, хотя я согласен, что оно не подтверждает, что оно все еще решает проблему. - person totallyNotLizards; 26.06.2014
comment
@configurator Ну, телефонные коды страны имеют свойство префикса, поэтому ваш пример (4 (420) 778-457800), если 4 - это код страны, а 420 - код города / области) не может быть реальным числом, однако вы указали, что знак + важен для обозначения того, являются ли первые цифры кодом страны - возможно, лучшим примером будет - person Peyton; 04.07.2014
comment
Это работает, но добавляет сложности в логику. - person JohnMerlino; 15.08.2014
comment
Не использует регулярные выражения. +1 - person John Shedletsky; 01.05.2015
comment
См. Также: technet.microsoft.com/en- us / library / cc728034 (v = ws.10) .aspx Если для набора номера в Windows используется TAPI, это может помочь. - person Ben; 08.09.2015
comment
Я создал общедоступную сущность, предоставляющую функцию ES6, основанную на регулярном выражении, предоставленном @AlbertBori. Отзывы приветствуются. - person Josh Habdas; 10.01.2016
comment
Номера Великобритании (+44) должны содержать 10 цифр после 0 / + 44. например 01234 567 890 - person mwfearnley; 10.03.2016
comment
@mwfearnley Не все есть с 9 и 7 (также есть бесплатные с 9 и 7) en.wikipedia. org / wiki / Telephone_numbers_in_the_United_Kingdom и в живой памяти длина изменилась - person mmmmmm; 22.03.2016
comment
Стою исправлюсь .. Я достаточно взрослый, чтобы помнить смену - жил в 0234 году :) - person mwfearnley; 23.03.2016
comment
Я размышляю: из-за британской тенденции писать числа в нестандартной форме +44 (0) Если это склонность многих людей, разве это не стандарт? (и чертовски раздражает, даже если я делаю это сам). - person Jmons; 02.05.2017
comment
как это могло быть подтверждено как лучший ответ честно - person fdsfdsfdsfds; 11.12.2017
comment
Неприемлемо, что, если вы не контролируете ввод? это не решает вопрос. - person Leo Gurdian; 27.01.2018
comment
Это отличный ответ. Это показывает, что вы должны преобразовать в целое число, а затем проверить это (предположительно, используя простой алгоритм). Эта часть подразумевается или, по крайней мере, кажется мне очевидной. Проверять номер телефона с помощью регулярного выражения на лету - это безумие. Кроме того ... что нужно проверить в первую очередь? Что это настоящий номер телефона? Почему? Если пользователь предоставляет неверный номер телефона, это их проблема. - person user428517; 18.04.2018
comment
это вообще не отвечает на вопрос. о единственном, что дает этот ответ, - это нормализовать ваш ввод. спрашивали не об этом. почему это принятый ответ? - person RisingSun; 28.01.2020

Оказывается, для этого есть что-то вроде спецификации, по крайней мере для Северной Америки, которая называется NANP. .

Вам нужно указать именно то, что вы хотите. Что такое юридические разделители? Пробелы, тире и точки? Без разделителя? Можно ли смешивать разделители (например, + 0.111-222.3333)? Как будут обрабатываться расширения (например, 111-222-3333 x 44444)? А как насчет специальных номеров, например 911? Код города будет необязательным или обязательным?

Вот регулярное выражение для 7- или 10-значного числа с разрешенными расширениями, разделителями являются пробелы, тире или точки:

^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$
person Community    schedule 23.09.2008
comment
здесь он без секции расширений (я заставляю пользователей вводить ext в отдельное поле): ^ (?: (?: \ +? 1 \ s * (?: [.-] \ s *)?)? (? : (\ s * ([2-9] 1 [02-9] | [2-9] [02-8] 1 | [2-9] [02-8] [02-9]) \ s *) | ([2-9] 1 [02-9] | [2-9] [02-8] 1 | [2-9] [02-8] [02-9])) \ s * (?: [ .-] \ s *)?)? ([2-9] 1 [02-9] | [2-9] [02-9] 1 | [2-9] [02-9] {2}) \ s * (?: [.-] \ s *)? ([0-9] {4}) $ - person aarona; 04.05.2010
comment
У меня это хорошо сработало. Мне нужно было обновить часть расширения, добавив косую черту перед #, иначе он говорит, что оттуда есть комментарий - person Brian Surowiec; 20.08.2010
comment
Как насчет добавления (и) в этот список разделителей? - person Jeremy Ricketts; 01.09.2010
comment
Вот версия, которая соответствует только 10-значным телефонным номерам (а не 7-значным, как 843-1212): /(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})/ - person Brian Armstrong; 07.09.2010
comment
10 цифр принимает () вокруг кода города и не позволяет использовать код страны до 1 (?:(?:(\s*\(?([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\)?\s*(?:[.-]\s*)?)([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4}) - person Brooke.; 09.01.2011
comment
@StevenSoroka Последние два года рядом со мной на столе лежит книга Джеффри Фридла, поскольку регулярные выражения - основная часть моей работы. Чтобы по-настоящему понять регулярные выражения, нужно время. Иногда читатели этого сайта просто ищут существующее решение, а не пишут собственное, особенно в доменах с большим количеством угловых случаев, таких как представление телефонных номеров. - person Justin R.; 29.03.2013
comment
@ fatcat1111 Я понимаю это, но большинство ответов здесь - это тоже одноразовые регулярные выражения, которые, вероятно, не подходят ни для одного из ваших угловых случаев. Затем они попадают на все веб-сайты, которые я пытаюсь использовать, и я не могу ввести свой почтовый индекс, номер телефона или адрес электронной почты, потому что кто-то использовал недолговечное регулярное выражение (например: + - допустимый символ в адресах электронной почты. ). Лучшие ответы на этой странице указывают пользователям на библиотеки, а не на нарисованные на салфетке регулярные выражения. - person Steven Soroka; 06.04.2013
comment
Будьте осторожны и проверяйте наличие неразрывных пробелов при копировании этих выражений. - person Nate Glenn; 17.12.2015
comment
Интересно, изменилось ли что-то с тех пор, как вы впервые опубликовали это? Он не соответствует хотя бы одному допустимому коду города: 410 (Мэриленд). 410 с 1991 года. - person ThisSuitIsBlackNot; 17.05.2016
comment
Кажется, это работает с каждым сценарием, который я использовал. Я даже ввел неверный код области, например, код области, который начинается с 1, недействителен, и он его поймал. AAA +++ Perfection для телефонных номеров в США .. - person Switch; 16.04.2019
comment
Пример того, где это регулярное выражение не работает: 866-411-1234 (потому что оно не разрешает обмен 411 согласно правилам NANPA, но это нормально для номеров 8xx). regex101.com/r/3DSYIr/1 - person drew010; 10.03.2020

.*

Если пользователи хотят дать вам свои номера телефонов, доверьте им это правильно. Если они не хотят отдавать его вам, то принуждение их к вводу действительного числа либо отправит их на сайт конкурента, либо заставит их ввести случайную строку, которая соответствует вашему регулярному выражению. У меня может возникнуть соблазн поискать номер горячей линии гороскопа премиум-класса и вместо этого ввести его.

Я бы также рассмотрел любое из следующего как допустимые записи на веб-сайте:

"123 456 7890 until 6pm, then 098 765 4321"  
"123 456 7890 or try my mobile on 098 765 4321"  
"ex-directory - mind your own business"
person Community    schedule 07.08.2009
comment
Я согласен с мнением здесь, но иногда приятно выполнить проверку, когда номер телефона действительно будет использоваться для чего-то важного в интересах пользователя. Лучшим примером здесь является авторизация кредитной карты для покупки. Если номер телефона неправильный, авторизация может завершиться ошибкой. - person Pointy; 10.11.2010
comment
Если пользователь не хочет вводить свой номер телефона, вы можете просто разрешить это поле быть необязательным, но разве это много, чтобы просить пользователя ввести действительный номер телефона, если они собираются ввести его? - person Joel McBeth; 06.12.2010
comment
Также роль проверки состоит в том, чтобы просто напомнить людям о необходимости добавить коды городов и т. Д., Которые они могли бы не забыть добавить, но которые невозможно угадать постфактум. - person Ben McIntyre; 23.02.2011
comment
@Pointy: Да, но даже если это действительный номер, это не означает, что это существующий номер, и даже если он существует, это не означает, что это номер пользователя. Если это так важно, вам нужно настроить автоматическую систему, которая будет звонить им, чтобы проверить ... Если ваш бюджет так сильно растягивается :) - person Benjol; 01.03.2011
comment
@Benjol, да, это правда - на мое личное мнение, вероятно, влияет тот факт, что на одном из моих ноутбуков есть липкая клавиша 5 :-) - person Pointy; 01.03.2011
comment
Я согласен с точки зрения удобства использования, но разрешение произвольного ввода может подвергнуть ваш веб-сайт атакам с использованием межсайтовых сценариев (XSS). Злоумышленник может внедрить JavaScript в строку вашего номера телефона в произвольной форме. - person Chris Peterson; 02.04.2011
comment
Иногда пользователям необходимо указать действующий номер телефона. Если вы заявите, что это часть ToS - дать один, они не могут дать поддельный без нарушения. Если вы хотя бы убедитесь с точки зрения проверки, что то, что они дали, синтаксически правильно, это избавит вас от многих головных болей. - person PlexQ; 30.03.2012
comment
Обычно я склоняюсь к такому образу мышления с пользовательским опытом. В основе действительного номера телефона в США - 10 цифр: ^(.*\d.*){10,}$. Это позволяет вводить его любым удобным для пользователя способом. Затем на серверной части удалите недопустимые символы. - person Cory Mawhorter; 28.09.2012
comment
@Pointy Но проверка регулярного выражения вам не поможет. Единственный способ проверить правильность номера телефона - это отправить ему сообщение (в случае мобильного телефона) И убедиться, что пользователь подтверждает, используя какой-то проверочный код. Это то, что вы делаете, когда важна правильность номера. Все остальное просто для удобства пользователя, чтобы защитить от некоторых (но не всех) опечаток и ничего не проверяет. - person Alex B; 16.11.2012
comment
@AlexB, конечно, я это понимаю, но если вы можете помочь мне отловить ошибку отсутствия цифры, это избавит меня от (небольших) неудобств, связанных с получением ошибки на стороне сервера, ее интерпретацией, повторным поиском поля и т. Д. - person Pointy; 16.11.2012
comment
Есть миллион случаев использования, когда это решение в виде простого текста является ответом. Но есть миллион случаев, когда это может вызвать множество проблем. Посмотрите, как вы используете номер телефона и почему вы его просите. Затем вы можете решить, какая методология подходит вам. Если вы не знаете, почему вы спрашиваете или как вы его используете, вам, вероятно, вообще не следует спрашивать номер телефона. - person Jason; 22.01.2013
comment
Верно, но тогда вы могли бы просто сделать что-нибудь вроде «когда не пусто, проверить». Что-то вроде if (!empty($telephone) && !validation_function($telephone)) { //throw_error }, тогда вы можете НЕ вводить свой номер. - person ; 03.09.2013
comment
Прохладный. Мой номер телефона: 1 'OR 1 = 1 - PWNED. См. xkcd.com/327 и owasp.org/index.php/Testing_for_SQL_Injection_ (OWASP-DV-005) - person Aaron Newton; 19.09.2013
comment
Ответ содержит глубочайшую мудрость. - person Ziggy; 08.01.2014
comment
В моем случае мне нужно было подтвердить номер телефона, поскольку это был самый простой способ определить, кто рассылал спам в форме. Это спамеры использовали неверные номера телефонов. Кроме того, это была форма запроса, поэтому мы планировали позвонить всем, кто ее заполнил, и номер телефона был обязательным полем. - person Evan Donovan; 24.01.2014
comment
@EvanDonovan Тогда вы пропустите мою запись, потому что я буду использовать фиктивный телефон, если только не хочу, чтобы вы мне перезвонили, что очень маловероятно - person mmmmmm; 10.04.2014
comment
@Mark: Меня это не слишком беспокоит. Очевидно, я не могу захватить все с помощью регулярного выражения. В этом случае спамеры не вводили никаких действительных данных в форму, тогда как я предполагаю, что если бы вы заполняли форму, вы, по крайней мере, вводили бы действительное электронное письмо. - person Evan Donovan; 11.04.2014
comment
Этот ответ не отвечает на вопрос - он просто способствует непереносимости форм, которая уже присуща всем нам. - person darkheartfelt; 08.01.2015
comment
@AaronNewton: выполнение проверки на уровне формы или использование регулярных выражений в любом случае небезопасно, есть лучшие способы предотвратить внедрение sql. - person Willem Van Onsem; 18.02.2015
comment
@CommuSoft, это правда. Однако лучшим утверждением могло бы быть не полагаться исключительно на регулярное выражение для предотвращения внедрения SQL. Я бы по-прежнему утверждал, что имеет смысл проверять заведомо неправильные или гнусные данные, например Можете ли вы представить себе случай, когда для номера телефона требуется что-либо, кроме буквенно-цифровых символов + базовая пунктуация, или он должен быть длиннее, чем длина поля в базе данных? Что касается последнего, то, вероятно, запутает или рассердит пользователя, если поле базы данных содержит 128 символов, но вы позволяете пользователю вводить 129 символов, что приводит к некоторой ошибке в пользовательском интерфейсе. - person Aaron Newton; 19.02.2015
comment
Этот ответ непочтителен и никоим образом не имеет отношения к вопросу. OP попросил помощи в проверке формата ввода от пользователя; не для вашего личного мнения о том, должен ли он. Возможный вариант использования: веб-сайт предназначен для внутреннего использования компанией - это не означает использование интрасети, скорее, у этой компании есть сотрудники, которые работают в полевых условиях и общаются с сотрудниками офиса через этот веб-сайт. Им нужно, чтобы человек ввел действительный номер телефона, по которому с ними можно связаться, как часть их должностных требований, и они хотят избежать простых ошибок, которые могут вызвать головную боль. - person Mike Manard; 24.07.2015
comment
. * - это регулярное выражение, которое будет проверять ноль или более символов любого типа как действительные, что не соответствует цели проверки номера телефона. - person lee; 13.10.2015
comment
Конечно, это не учитывает формы, для которых требуется номер телефона. В настоящее время я создаю приложение для отслеживания лицензионной информации в нашей организации. Требуются номера телефонов поставщиков, поэтому я определенно хотел бы их подтвердить. - person DrewB; 12.10.2016
comment
Если вы хотите по-настоящему подтвердить номер телефона ... ТЕЛЕФОН ПО ТЕЛЕФОНУ !! Это похоже на нелепые регулярные выражения, которые люди придумали для проверки адреса электронной почты .. . Если вы действительно заботитесь о том, что адрес электронной почты действителен, тогда ОТПРАВИТЕ ИМ ЭЛЕКТРОННУЮ ПОЧТУ !! - person Tom Lord; 26.10.2016
comment
-1, потому что вы можете сделать это поле НЕ обязательным и все равно его нужно будет проверять, чтобы предотвратить случайные орфографические ошибки. Часть ответа «или попробуйте мой мобильный» - это просто чушь, ИМО. Вы передаете формату решение пользователя, следовать ему или нет. Только не делайте этого обязательным, вот и все. - person Unicorn; 16.12.2016
comment
Вопрос был не в проверке ввода данных пользователем. Это может быть проверка списка агрегированных телефонных номеров из нескольких систем, собранных в разное время с помощью разных форм. Грязные данные поступают из самых разных источников. - person Yarin; 09.11.2017
comment
Я думаю, ты ошибся. Это несложный способ получить от пользователя правильный номер, потому что, как вы упомянули, пользователь может в конечном итоге сбежать и ввести номер другого человека. Это проверка номера для классификации информации, чтобы в будущем у нас была чистая информация без какой-либо дополнительной информации и лишних символов от пользователя для возможного использования в будущем. - person Nabi K.A.Z.; 24.02.2019
comment
Существа вопроса ОП - не вопрос, на который нужно отвечать. Я оставляю этот комментарий только потому, что SO попросил меня, но теперь жалуется на ссылку на мой голос. - person Altimus Prime; 29.11.2019

Я также предлагаю посмотреть библиотеку Google "libphonenumber". Я знаю, что это не регулярное выражение, но оно делает именно то, что вы хотите.

Например, он распознает, что:

15555555555

- возможное число, но не действительное. Он также поддерживает страны за пределами США.

Основные функции:

  • Разбор / форматирование / проверка телефонных номеров для всех стран / регионов мира.
  • getNumberType - получает тип номера исходя из самого номера; возможность различать фиксированные, мобильные, бесплатные, платные, общие, VoIP и личные номера (когда это возможно).
  • isNumberMatch - получает уровень уверенности в том, могут ли два числа быть одинаковыми.
  • _4 _ / _ 5_ - предоставляет действительные примеры номеров для всех стран / регионов с возможностью указания типа необходимого примера телефонного номера.
  • isPossibleNumber - быстро угадать, является ли номер возможным телефонным номером, используя только информацию о длине, намного быстрее, чем полная проверка.
  • isValidNumber - полная проверка телефонного номера для региона с использованием информации о длине и префиксе.
  • AsYouTypeFormatter - форматирует телефонные номера на лету, когда пользователи вводят каждую цифру.
  • findNumbers - находит числа при вводе текста.
  • PhoneNumberOfflineGeocoder - предоставляет географическую информацию, относящуюся к номеру телефона.

Примеры

Самая большая проблема с подтверждением номера телефона - это культурная зависимость.

  • America
    • (408) 974–2042 is a valid US number
    • (999) 974–2042 - недействительный номер в США
  • Australia
    • 0404 999 999 is a valid Australian number
    • (02) 9999 9999 также является действительным австралийским номером.
    • (09) 9999 9999 - недействительный номер в Австралии

Регулярное выражение подходит для проверки формата номера телефона, но на самом деле оно не позволяет проверить действительность номера телефона.

Я бы посоветовал пропустить простое регулярное выражение для проверки вашего номера телефона и использовать такую ​​библиотеку, как libphonenumber (ссылка на GitHub проект).

Представляем libphonenumber!

Используя один из ваших более сложных примеров, 1-234-567-8901 x1234, вы получите следующие данные из libphonenumber (ссылка на онлайн-демонстрацию):

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results:

E164 format                    +12345678901
Original format                (234) 567-8901 ext. 123
National format                (234) 567-8901 ext. 123
International format           +1 234-567-8901 ext. 123
Out-of-country format from US  1 (234) 567-8901 ext. 123
Out-of-country format from CH  00 1 234-567-8901 ext. 123

Таким образом, вы не только узнаете, действителен ли номер телефона (что он есть), но и получите согласованное форматирование номера телефона в вашем регионе.

В качестве бонуса у libphonenumber есть несколько наборов данных для проверки действительности телефонных номеров, поэтому проверка номера, например +61299999999 (международная версия _ 22_) возвращается как действительное число с форматированием:

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results

E164 format                    +61299999999
Original format                61 2 9999 9999
National format                (02) 9999 9999
International format           +61 2 9999 9999
Out-of-country format from US  011 61 2 9999 9999
Out-of-country format from CH  00 61 2 9999 9999

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

PhoneNumberOfflineGeocoder Results
Location        Australia

PhoneNumberToTimeZonesMapper Results
Time zone(s)    [Australia/Sydney]

Но недействительный австралийский номер телефона ((09) 9999 9999) возвращает, что это неверный номер телефона.

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     false

В версии Google есть код для Java и Javascript, но люди также внедрили библиотеки для других языков, которые используют набор данных телефонных номеров Google i18n:

Если вы не уверены, что всегда будете принимать номера из одной локали, и они всегда будут в одном формате, я настоятельно рекомендую не писать для этого свой собственный код и использовать libphonenumber для проверки и отображения номеров телефонов.

person Community    schedule 26.03.2013
comment
Обратите внимание, что теперь есть порт Go по адресу: github.com/ttacon/libphonenumber - person michaelhanson; 12.09.2016
comment
При проверке, является ли это возможным числом, разве вам не нужно указывать код страны? Я использую версию PHP, и если я введу британский номер, например (замените 0 действительными числами) 07700000000, я получаю Missing or invalid default region. ошибку. Но если я укажу код страны, он пройдет. - person BugHunterUK; 29.11.2016
comment
К вашему сведению: эта библиотека не поддерживает некоторые страны, вопросы phpinterviewquestions. co.in/blog/ionic/ - person sijo vijayan; 22.07.2017
comment
@BugHunterUK (и любой, кто сталкивается с этим вопросом и задается вопросом о том же) при синтаксическом анализе числа, вы можете указать ожидаемый регион, и библиотека будет искать немеждународные номера в этом регионе. Если вы не укажете, он отклонит все, что не соответствует допустимому международному формату. - person IMSoP; 22.03.2018
comment
Рассмотрим github.com/nyaruka/phonenumbers, поскольку он стал официальным пакетом Go, рекомендованным Google, а не libphonenumber. . - person DeeZone; 06.05.2019
comment
Я могу подтвердить то, что говорит @BugHunterUK. Потребовалось время, чтобы добраться туда, но результат оказался именно таким, как и ожидалось - местные номера принимаются в любом формате плюс все полностью определенные международные форматы. - person dimplex; 09.07.2020

/^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i

Это соответствует:

 - (+351) 282 43 50 50
 - 90191919908
 - 555-8909
 - 001 6867684
 - 001 6867684x1
 - 1 (234) 567-8901
 - 1-234-567-8901 x1234
 - 1-234-567-8901 ext1234
 - 1-234 567.89/01 ext.1234
 - 1(234)5678901x1234
 - (123)8575973
 - (0055)(123)8575973

На $ n экономится:

  1. Индикатор страны
  2. Номер телефона
  3. Расширение

Вы можете протестировать его на https://www.regexpal.com/?fam=99127.

person Community    schedule 07.01.2014
comment
Это было самое полное регулярное выражение, которое я когда-либо видел. Это легко обойти, пока вы не удалите ^ и $, иначе я смогу обойти это с помощью [111] [111] [1111] или 111--111--1111 и т.п. (извините, удалил мой последний комментарий) - person bafromca; 08.03.2014
comment
Не могли бы вы перефразировать? Я не могу этого понять: легко обойтись, пока вы не удалите ^ и $, иначе я смогу обойти это с помощью [111] [111] [1111]. Означает ли это, что он проверяет «[111] [111] [1111]», когда вы берете ^ и $? - person Ismael Miguel; 08.03.2014
comment
Я обошел ваше регулярное выражение, используя [111] [111] [1111] и 111--111--1111, пока я не удалил ^ и $ из регулярного выражения. - person bafromca; 08.03.2014
comment
Как я уже спрашивал, какой движок вы используете? 111-111-1111 отлично проверяет (синтаксически второй действителен), а [111] [111] [1111] не проверяет (как и ожидалось) - person Ismael Miguel; 08.03.2014
comment
gethifi.com/tools/regex, и я имел в виду 111--111--1111, как упоминалось выше. - person bafromca; 08.03.2014
comment
111--111--1111 недействителен: i62.tinypic.com/2rnhr7k.png (отлично) и [111] [111] [1111] также недействителен: i58.tinypic.com/9ru64y.png (как и ожидалось) - person Ismael Miguel; 08.03.2014
comment
позвольте нам продолжить это обсуждение в чате - person bafromca; 08.03.2014
comment
^^^ Это отличный пример того, почему темы комментариев НЕ должны идти в чат. Мне очень интересно, чем закончился этот разговор, и мне нужно знать, достаточно ли прочен этот ReGex для использования в моем приложении. К сожалению, разговора в чате больше нет. - person Matt Cashatt; 18.07.2014
comment
Если честно, я не ходил в чат. После того, как я несколько раз просил объяснений, я остался без информации. Вы всегда можете попробовать это сами со всеми видами чисел, которые найдете в Интернете, в различных форматах. Одна вещь, которую я пробовал с этим, - использовать несколько телефонных номеров, но он не работает так хорошо, если вокруг них есть пробелы. И мне нужно найти решение, чтобы подсчитать количество цифр и обеспечить соблюдение определенной суммы. - person Ismael Miguel; 19.07.2014
comment
Как мне сделать так, чтобы он мог извлекать номер из строки в любом месте, где может быть номер телефона? - person Kousha; 17.02.2017
comment
@Kousha Удалите ^ и $, и он должен работать с множеством ложных срабатываний. - person Ismael Miguel; 17.02.2017
comment
@Kousha Это ожидалось. Вы пытаетесь заставить Javascript RegExp работать на PHP с помощью PCRE. Его нужно немного переписать. Что выходит за рамки этого вопроса. Используя regex101.com, вставив туда регулярное выражение и перейдя в инструменты - ›генератор кода, вы получите следующее: /(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\\\/]?){0,})(?:[\-\.\ \\\\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\\\/]?(\d+))?/i. И этот работает. - person Ismael Miguel; 17.02.2017

Хотя ответ на удаление всех пробелов прост, на самом деле он не решает поставленную проблему, а именно найти регулярное выражение. Возьмем, к примеру, мой тестовый скрипт, который загружает веб-страницу и извлекает все номера телефонов с помощью регулярного выражения. Поскольку вам в любом случае понадобится регулярное выражение, вы также можете заставить регулярное выражение делать всю работу. Я придумал это:

1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?

Вот скрипт на Perl для его проверки. При совпадении $ 1 содержит код города, $ 2 и $ 3 - номер телефона, а $ 5 - расширение. Мой тестовый сценарий загружает файл из Интернета и печатает в нем все телефонные номера.

#!/usr/bin/perl

my $us_phone_regex =
        '1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?';


my @tests =
(
"1-234-567-8901",
"1-234-567-8901 x1234",
"1-234-567-8901 ext1234",
"1 (234) 567-8901",
"1.234.567.8901",
"1/234/567/8901",
"12345678901",
"not a phone number"
);

foreach my $num (@tests)
{
        if( $num =~ m/$us_phone_regex/ )
        {
                print "match [$1-$2-$3]\n" if not defined $4;
                print "match [$1-$2-$3 $5]\n" if defined $4;
        }
        else
        {
                print "no match [$num]\n";
        }
}

#
# Extract all phone numbers from an arbitrary file.
#
my $external_filename =
        'http://web.textfiles.com/ezines/PHREAKSANDGEEKS/PnG-spring05.txt';
my @external_file = `curl $external_filename`;
foreach my $line (@external_file)
{
        if( $line =~ m/$us_phone_regex/ )
        {
                print "match $1 $2 $3\n";
        }
}

Изменить:

Вы можете изменить \ W * на \ s * \ W? \ S * в регулярном выражении, чтобы немного его сжать. Я не думал о регулярном выражении с точки зрения, скажем, проверки пользовательского ввода в форме, когда я его писал, но это изменение позволяет использовать регулярное выражение для этой цели.

'1?\s*\W?\s*([2-9][0-8][0-9])\s*\W?\s*([2-9][0-9]{2})\s*\W?\s*([0-9]{4})(\se?x?t?(\d*))?';
person Community    schedule 23.09.2008
comment
К вашему сведению, регулярное выражение также соответствует: (4570457-6789, что было бы довольно распространенной опечаткой. Группы соответствий также искажаются: rubular.com/r/TaTP0mHL5c - person SooDesuNe; 20.02.2013
comment
@SooDesuNe Добавление (^|[^\d\n]) (с включенным многострочным флагом) позволяет избежать общей проблемы, гарантируя, что ей не предшествует что-то числовое. - person btown; 23.03.2017
comment
Обратите внимание, что это ориентировано на Северную Америку - оно не соответствует 44 7911 123456 - person Ben Wheeler; 25.03.2020

Я ответил на этот вопрос по другому вопросу SO, прежде чем решил также включить свой ответ в качестве ответа в этой теме, потому что никто не обращался к тому, как требовать / не требовать элементы, просто раздавая регулярные выражения: Регулярное выражение работает неправильно, сопоставляет неожиданные вещи

Из моего сообщения на этом сайте я создал краткое руководство, чтобы помочь любому создать собственное регулярное выражение для желаемого формата номера телефона, о чем я предупреждаю (как и на другом сайте), что, если вы слишком ограничиваете, вы можете не получить желаемых результатов, и не существует единого решения для приема всех возможных телефонных номеров в мире - только то, что вы решите принять в качестве предпочтительного формата. Используйте на свой риск.

Краткая шпаргалка

  • Начните выражение: /^
  • Если вам нужен пробел, используйте: [\s] или \s
  • Если вы хотите требовать скобки, используйте: [(] и [)]. Использование \( и \) некрасиво и может сбивать с толку.
  • Если вы хотите, чтобы что-то было необязательным, поставьте после него ?
  • Если вам нужен дефис, просто введите - или [-]. Однако, если вы не поместите его первым или последним в ряду других символов, вам может потребоваться его экранировать: \-
  • Если вы хотите использовать разные варианты в слоте, заключите их в скобки: [-.\s] потребуется дефис, точка или пробел. Знак вопроса после последней скобки сделает все это необязательными для этого слота.
  • \d{3}: требуется трехзначный номер: 000-999. Сокращение для [0-9][0-9][0-9].
  • [2-9]: для этого слота требуется цифра 2-9.
  • (\+|1\s)?: примите плюс или 1 и пробел (вертикальная черта, |, равно или) и сделайте это необязательным. Знак плюс должен быть экранирован.
  • Если вы хотите, чтобы определенные числа соответствовали слоту, введите их: [246] потребуется 2, 4 или 6. (?:77|78) или [77|78] потребуется 77 или 78.
  • $/: Завершить выражение
person Community    schedule 14.08.2014
comment
Это очень полезно, но я сомневаюсь и ищу выражение {min, max}. Вы можете помочь? - person Ataboy Josef; 07.01.2015
comment
Если мы говорим об одной цифре (и вы можете сопоставить ее в соответствии с этим), посмотрите блок [2-9], который я там поместил. Это означает, что ваш минимум равен 2, а ваш максимум равен 9. Отрегулируйте соответственно. - person vapcguy; 08.01.2015

Я писал проще всего (хотя мне и не понадобилась точка).

^([0-9\(\)\/\+ \-]*)$

Как упоминалось ниже, он проверяет только символы, а не их структуру / порядок.

person Community    schedule 04.02.2010
comment
это проверяет тонны чисел, которые технически недействительны. вроде, - + () () ()) ()))). Научитесь читать регулярные выражения, чтобы понимать, что вы делаете. - person Steven Soroka; 28.03.2013
comment
@StevenSoroka технически может допускать множество недействительных случаев, но когда мы думаем о том, чтобы просто помочь пользователю избежать распространенных ошибок с помощью простейшего возможного решения, это выход :) - person happyhardik; 23.08.2013
comment
это также соответствует пробелу, пустой строке - person Wasim A.; 16.09.2013
comment
@HappyHardik. Действительно. Простой и мощный, для базовой проверки позволяет пользователю вводить более одной точки, тире, скобки или плюса. - person dijipiji; 04.02.2014
comment
Просто использовал, и он во многом неверен. Например, номер телефона в Великобритании может начинаться с +44 или в номере телефона может быть (0). Но это не соответствует вашему регулярному выражению. Я бы порекомендовал ответ @Ismael Miguel. Он работает нормально, и я бы порекомендовал вам пересмотреть свой ответ. - person Stelios Voskos; 29.07.2015

Обратите внимание, что удаление символов () не работает для обычного стиля написания номеров Великобритании: +44 (0) 1234 567890, что означает набор либо международного номера:
+441234567890
, либо набора номера в Великобритании 01234567890

person Community    schedule 21.03.2010
comment
ты решил это? - person Sultan Ali; 03.03.2021

Если вы просто хотите убедиться, что у вас нет случайного мусора в поле (то есть от спамеров форм), это регулярное выражение должно работать хорошо:

^[0-9+\(\)#\.\s\/ext-]+$

Обратите внимание, что у него нет каких-либо специальных правил для количества цифр или того, какие числа действительны в этих цифрах, он просто проверяет, что только цифры, круглые скобки, тире, плюс, пробел, фунт, звездочка, точка, запятая или буквы e, x, t присутствуют.

Он должен быть совместим с международными номерами и форматами локализации. Предвидите ли вы необходимость разрешить использование квадратных, фигурных или угловых скобок для некоторых регионов? (в настоящее время они не включены).

Если вы хотите поддерживать правила на основе цифр (например, в кодах регионов США и префиксы (коды обмена) должны находиться в диапазоне 200-999), что ж, удачи вам. Поддерживать сложный набор правил, который в любой момент в будущем может устареть в любой стране мира, не звучит весело.

И хотя удаление всех / большинства нечисловых символов может хорошо работать на стороне сервера (особенно если вы планируете передавать эти значения в программу набора номера), вы можете не захотеть обрабатывать ввод пользователя во время проверки, особенно если вы хотите, чтобы они внести исправления в другую область.

person Community    schedule 15.08.2012

Вы просматривали RegExLib?

Ввод номера телефона в США вернул целый список возможностей.

person Community    schedule 23.09.2008
comment
Похоже, это отличный способ интегрировать малоизвестные ошибки в ваш код. - person Tom Lord; 26.10.2016
comment
Следует избегать ответов, содержащих только ссылки, потому что они могут сломаться в будущем и сделать сообщение бесполезным. Статические решения всегда необходимы для поддержания ценности ответа. Если вы хотите порекомендовать гиперссылку, добавьте ее в качестве комментария под вопросом. - person mickmackusa; 31.07.2020

Моя попытка неограниченного регулярного выражения:

/^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/

Принимает:

+(01) 123 (456) 789 ext555
123456
*44 123-456-789 [321]
123456
123456789012345678901234567890123456789012345
*****++[](][((( 123456tteexxttppww

Отклоняет:

mob 07777 777777
1234 567 890 after 5pm
john smith
(empty)
1234567890123456789012345678901234567890123456
911

Вы должны очистить его для отображения. Однако после проверки может быть числом.

person Community    schedule 09.03.2012

Вот замечательный паттерн, который наиболее точно соответствует проверке, которой мне нужно было добиться. Я не являюсь первоначальным автором, но я думаю, что этим стоит поделиться, поскольку я нашел эту проблему очень сложной и без краткого или широко полезного ответа.

Следующее регулярное выражение будет улавливать широко используемые комбинации цифр и символов в различных форматах глобальных телефонных номеров:

/^\s*(?:\+?(\d{1,3}))?([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/gm

Положительный:
+42 555.123.4567
+ 1- (800) -123-4567
+7 555 1234567
+7 (926) 1234567
(926) 1234567
+79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567
469 123 45 67
89261234567
8 (926) 1234567
926.123.4567
415-555-1234
650-555-2345
(416) 555 -3456
202 555 4567
4035555678
1 416 555 9292

Отрицательные:
926 3 4
8 800 600-APPLE

Исходный источник: http://www.regexr.com/38pvb

person Community    schedule 23.04.2015
comment
Это имеет некоторую ограниченную поддержку расширений. Он соответствует 616-555-1234 x567, но не 616-555-1234 ext. 567. - person Jon Schneider; 24.06.2016
comment
Ложное срабатывание, например .------- ((((((55555555 или 99999999999999999999999 - person mikep; 23.11.2017
comment
Он не проверяет номер макдональдса Nitherland +31 76596 4192 (я просто проверял случайные числа) - person BIOHAZARD; 09.12.2018

Я обнаружил, что это работает довольно хорошо:

^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$

Он работает для следующих числовых форматов:

1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
1-234-567-8901 ext. 1234
(+351) 282 433 5050

Обязательно используйте глобальные И многострочные флаги, чтобы убедиться.

Ссылка: http://www.regexr.com/3bp4b

person Community    schedule 11.09.2015

Вот моя лучшая попытка. Он поддерживает форматы, указанные выше, но я уверен, что мне не хватает других возможных форматов.

^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$
person Community    schedule 23.09.2008
comment
Работал как шарм! Спасибо, что поделился - person KdPisda; 29.01.2021

Если вы говорите о проверке формы, регулярное выражение для проверки правильного значения, а также правильных данных будет чрезвычайно сложным из-за различных стандартов страны и поставщиков. Также будет сложно идти в ногу со временем.

Я интерпретирую вопрос как поиск в целом допустимого шаблона, который может быть внутренне непротиворечивым - например, имеющий действительный набор чисел, но не подтверждающий, что магистральная линия, обмен и т. Д. Соответствует действительному шаблону для префикса кода страны .

Северная Америка проста, и для международного общения я предпочитаю использовать «идиоматический» шаблон, который охватывает способы, которыми люди указывают и запоминают свои номера:

^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$

Североамериканский паттерн гарантирует, что при включении одной круглой скобки будут включены обе. Для международных счетов необязательный начальный знак "+" и код страны. После этого вы в идиоме. Допустимые совпадения:

  • (xxx)xxx-xxxx
  • (xxx)-xxx-xxxx
  • (xxx)xxx-xxxx x123
  • 12 1234 123 1 x1111
  • 12 12 12 12 12
  • 12 1 1234 123456 x12345
  • +12 1234 1234
  • +12 12 12 1234
  • +12 1234 5678
  • +12 12345678

Это может быть предвзятым, поскольку мой опыт ограничен Северной Америкой, Европой и небольшой частью Азии.

person Community    schedule 10.04.2009
comment
Я пытался реализовать вышеизложенное в моем сценарии проверки javascript, но продолжаю получать invalid quantifier ошибку. Есть идеи о том, что я делаю неправильно? - person Jannis; 18.10.2010
comment
Я бы добавил тривиальный случай, когда телефон указан без символов, но, возможно, с пробелами и кодом страны, в Европе это типично для местных и мобильных номеров: 676412342, 676 46 32 12, 676463212 - person rupps; 20.04.2015

Мое чутье подкрепляется количеством ответов на эту тему - что существует практически бесконечное количество решений этой проблемы, ни одно из которых не будет элегантным.

Честно говоря, я бы порекомендовал вам не пытаться проверять номера телефонов. Даже если бы вы могли написать большой и сложный валидатор, который разрешал бы все различные допустимые форматы, он в конечном итоге разрешил бы практически все, даже отдаленно напоминающее номер телефона.

На мой взгляд, наиболее элегантным решением является проверка минимальной длины, не более того.

person Community    schedule 14.04.2011
comment
Попробовав несколько из них и просмотрев существующие данные и отзывы пользователей, я склонен согласиться ... - person Christopher King; 17.01.2014
comment
Однако иногда вам нужно выполнить проверку. Если я отправляю коды подтверждения, я не могу просто отправить код в любой случайный мусор, который спаммер ввел в это поле. Я хочу убедиться, что этот номер вероятно является номером телефона, прежде чем тратить ресурсы на его отправку. - person zfj3ub94rf576hc4eegm; 24.04.2020

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

((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

or

((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}

будет соответствовать этим:

+63.917.123.4567  
+63-917-123-4567  
+63 917 123 4567  
+639171234567  
09171234567  

Первый будет соответствовать ЛЮБОМУ двузначному коду страны, а второй - исключительно коду страны Филиппин.

Протестируйте здесь: http://refiddle.com/1ox

person Community    schedule 18.01.2012
comment
Спасибо. Как насчет стационарных номеров с кодом города, например 028231234? Мне интересно, являются ли коды городов только 2-3-значными числами и всегда ли им предшествует 0? - person stormwild; 26.02.2014

Вам будет сложно работать с международными номерами с помощью одного / простого регулярного выражения, см. этот пост о трудностях международных (и даже североамериканских) телефонных номеров.

Вам нужно проанализировать первые несколько цифр, чтобы определить код страны, а затем действовать по-разному в зависимости от страны.

Помимо этого - список, который вы предоставили, не включает другой распространенный в США формат - исключая начальную цифру 1. Большинство сотовых телефонов в США не требуют этого, и это начнет сбивать с толку молодое поколение, если они не наберут номер на международном уровне.

Вы правильно определили, что это сложная проблема ...

-Адам

person Community    schedule 23.09.2008
comment
Не предложенное решение. ВОЗМОЖНО. То, что это сложно или сложно, не означает, что вам нужно просто вскинуть руки вверх. - person Eric Hodonsky; 29.03.2017

Прочитав эти ответы, похоже, что не было простого регулярного выражения, которое могло бы анализировать кучу текста и извлекать телефонные номера в любом формате (включая международный со знаком плюс и без него).

Вот что я недавно использовал для клиентского проекта, где нам пришлось преобразовать все номера телефонов в любом формате в ссылки tel :.

До сих пор он работал со всем, что они на него бросали, но если возникнут ошибки, я обновлю этот ответ.

Регулярное выражение:

/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/

Функция PHP для замены всех телефонных номеров ссылками tel: (на случай, если кому-то интересно):

function phoneToTel($number) {
    $return = preg_replace('/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
    return $return;
}
person Community    schedule 08.07.2014
comment
Это регулярное выражение соответствует +1 1234562222222222222222222222. - person Varda Elentári; 13.10.2015
comment
почему бы просто не вернуться? - person thexande; 09.03.2017
comment
Ложноположительный результат для 9999999999999999999999999999999999999 - person Ben Wheeler; 25.03.2020

Я считаю, что Number :: Phone :: US и Regexp :: Common (в частности, источник Regexp :: Common :: URI :: RFC2806) Perl модули могут помочь.

Вопрос, вероятно, следует задать более подробно, чтобы объяснить цель проверки чисел. Например, 911 - допустимый номер в США, но 911x не для любого значения x. Это необходимо для того, чтобы телефонная компания могла рассчитать, когда вы закончите набор номера. Есть несколько вариантов этого вопроса. Но ваше регулярное выражение не проверяет часть кода области, так что это не вызывает беспокойства.

Как и при проверке адресов электронной почты, даже если у вас есть действительный результат, вы не можете узнать, назначен ли он кому-то, пока не попробуете его.

Если вы пытаетесь проверить вводимые пользователем данные, почему бы не нормализовать результат и не покончить с этим? Если пользователь вводит число, которое вы не можете распознать как действительное, либо сохраните его как введенное, либо удалите недопустимые символы. Number :: Phone :: Normalize Модуль Perl может стать источником вдохновения.

person Community    schedule 23.09.2008
comment
Я собираюсь рискнуть и сказать, что использование службы 911 в качестве номера телефона, вероятно, является плохой идеей почти для всех приложений этого регулярного выражения. Впрочем, неплохой улов. - person Nicholas Flynt; 11.07.2012

Я работаю в компании по исследованию рынка, и нам приходится фильтровать эти типы входных данных все время. Вы слишком усложняете это. Просто удалите не буквенно-цифровые символы и посмотрите, есть ли расширение.

Для дальнейшего анализа вы можете подписаться на одного из многих провайдеров, который предоставит вам доступ к базе данных действительных номеров, а также сообщит вам, стационарные они или мобильные, отключены и т. Д. Это стоит денег.

person Community    schedule 23.09.2008
comment
Проверка? 123% $) *% () $ * () # 456 * () * $ # (* (# $ @ 8908 будет соответствовать вашему предлагаемому решению. - person PlexQ; 30.03.2012
comment
@PlexQ 555-123-1234, 07777777777, 90210, 01.01.1901 - пользователи изобретательны в том, чтобы забивать мусор через валидацию. Лучше не ставить галочку перед теми, у кого действительно есть какие-то странные данные, используя чрезмерно ограничительную проверку и сообщая им, что они неправы. - person ReactiveRaven; 29.04.2012

Замените символы форматирования, затем проверьте оставшиеся на соответствие телефону. В PHP

 $replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed
 preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );

Нарушение такого сложного регулярного выражения может быть столь же эффективным, но гораздо более простым.

person Community    schedule 21.07.2009

Я нашел это кое-что интересным. Я не тестировал, но похоже, что это сработает

<?php
/*
string validate_telephone_number (string $number, array $formats)
*/

function validate_telephone_number($number, $formats)
{
$format = trim(ereg_replace("[0-9]", "#", $number));

return (in_array($format, $formats)) ? true : false;
}

/* Usage Examples */

// List of possible formats: You can add new formats or modify the existing ones

$formats = array('###-###-####', '####-###-###',
                 '(###) ###-###', '####-####-####',
                 '##-###-####-####', '####-####', '###-###-###',
                 '#####-###-###', '##########');

$number = '08008-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '123-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1800-1234-5678';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '(800) 555-123';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1234567890';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}
?>
person Community    schedule 04.01.2011
comment
Ваше сообщение, похоже, указывает на то, что вы не писали этот код. Не могли бы вы процитировать источник? - person Alastair Irvine; 30.09.2013
comment
bitrepository.com/how-to-validate-a-telephone- number.html выглядит как источник. - person James Paterson; 12.01.2016

Вам, вероятно, будет лучше использовать для этого маскированный ввод. Таким образом, пользователи могут вводить ТОЛЬКО числа, а вы можете форматировать их так, как считаете нужным. Я не уверен, что это для веб-приложения, но если это так, есть плагин jQuery, который предлагает несколько вариантов для этого.

http://digitalbush.com/projects/masked-input-plugin/

В своем руководстве они даже рассказывают, как маскировать ввод номера телефона.

person Community    schedule 11.08.2011

Вот тот, который хорошо работает в JavaScript. Это строка, потому что это то, чего ожидал виджет Dojo.

Он соответствует 10-значному номеру NANP для Северной Америки с дополнительным расширением. В качестве разделителей принимаются пробелы, тире и точки.

"^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$"
person Community    schedule 13.05.2012

Я боролся с той же проблемой, пытаясь сделать свое приложение перспективным, но эти ребята заставили меня двигаться в правильном направлении. Я на самом деле не проверяю сам номер, чтобы узнать, работает он или нет, я просто пытаюсь убедиться, что была введена серия чисел, которые могут иметь или не иметь расширение.

В худшем случае, если бы пользователю приходилось извлекать неформатированный номер из XML-файла, он все равно просто вводил бы числа в цифровую клавиатуру телефона 012345678x5, и не было реальной причины сохранять его красивым. Такой тип RegEx выйдет для меня примерно так:

\d+ ?\w{0,9} ?\d+
  • 01234467 extension 123456
  • 01234567x123456
  • 01234567890
person Community    schedule 21.07.2009

Я склонен согласиться с тем, что убирать нецифровые числа и просто принимать то, что там лучше. Может быть, чтобы убедиться, что присутствует хотя бы пара цифр, хотя это запрещает что-то вроде буквенного телефонного номера, например, «ASK-JAKE».

Вот пара простых выражений Perl:

@f = /(\d+)/g;
tr/0-9//dc;

Используйте первый, чтобы держать группы цифр вместе, что может дать подсказки форматирования. Используйте второй, чтобы тривиально отбросить все нецифровые.

Беспокоит ли вас то, что может потребоваться пауза, а затем ввести дополнительные ключи? Или что-то вроде 555-1212 (ждите гудка) 123?

person Community    schedule 23.09.2008

    pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" 
    validateat="onsubmit"

Должен заканчиваться цифрой, может начинаться с (или + или цифры, и может содержать + - (или)

person Community    schedule 28.02.2011

Для всех, кто хочет сделать что-то подобное с ирландскими номерами мобильных телефонов, вот простой способ сделать это:

http://ilovenicii.com/?p=87

PHP


<?php
$pattern = "/^(083|086|085|086|087)\d{7}$/";
$phone = "087343266";

if (preg_match($pattern,$phone)) echo "Match";
else echo "Not match";

По этой ссылке также есть решение JQuery.

РЕДАКТИРОВАТЬ:

Решение jQuery:

    $(function(){
    //original field values
    var field_values = {
            //id        :  value
            'url'       : 'url',
            'yourname'  : 'yourname',
            'email'     : 'email',
            'phone'     : 'phone'
    };

        var url =$("input#url").val();
        var yourname =$("input#yourname").val();
        var email =$("input#email").val();
        var phone =$("input#phone").val();


    //inputfocus
    $('input#url').inputfocus({ value: field_values['url'] });
    $('input#yourname').inputfocus({ value: field_values['yourname'] });
    $('input#email').inputfocus({ value: field_values['email'] }); 
    $('input#phone').inputfocus({ value: field_values['phone'] });



    //reset progress bar
    $('#progress').css('width','0');
    $('#progress_text').html('0% Complete');

    //first_step
    $('form').submit(function(){ return false; });
    $('#submit_first').click(function(){
        //remove classes
        $('#first_step input').removeClass('error').removeClass('valid');

        //ckeck if inputs aren't empty
        var fields = $('#first_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<12 || value==field_values[$(this).attr('id')] ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }
        });        

        if(!error) {
            if( $('#password').val() != $('#cpassword').val() ) {
                    $('#first_step input[type=password]').each(function(){
                        $(this).removeClass('valid').addClass('error');
                        $(this).effect("shake", { times:3 }, 50);
                    });

                    return false;
            } else {   
                //update progress bar
                $('#progress_text').html('33% Complete');
                $('#progress').css('width','113px');

                //slide steps
                $('#first_step').slideUp();
                $('#second_step').slideDown();     
            }               
        } else return false;
    });

    //second section
    $('#submit_second').click(function(){
        //remove classes
        $('#second_step input').removeClass('error').removeClass('valid');

        var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;  
        var fields = $('#second_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<1 || value==field_values[$(this).attr('id')] || ( $(this).attr('id')=='email' && !emailPattern.test(value) ) ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }


        function validatePhone(phone) {
        var a = document.getElementById(phone).value;
        var filter = /^[0-9-+]+$/;
            if (filter.test(a)) {
                return true;
            }
            else {
                return false;
            }
        }

        $('#phone').blur(function(e) {
            if (validatePhone('txtPhone')) {
                $('#spnPhoneStatus').html('Valid');
                $('#spnPhoneStatus').css('color', 'green');
            }
            else {
                $('#spnPhoneStatus').html('Invalid');
            $('#spnPhoneStatus').css('color', 'red');
            }
        });

     });

        if(!error) {
                //update progress bar
                $('#progress_text').html('66% Complete');
                $('#progress').css('width','226px');

                //slide steps
                $('#second_step').slideUp();
                $('#fourth_step').slideDown();     
        } else return false;

    });


    $('#submit_second').click(function(){
        //update progress bar
        $('#progress_text').html('100% Complete');
        $('#progress').css('width','339px');

        //prepare the fourth step
        var fields = new Array(
            $('#url').val(),
            $('#yourname').val(),
            $('#email').val(),
            $('#phone').val()

        );
        var tr = $('#fourth_step tr');
        tr.each(function(){
            //alert( fields[$(this).index()] )
            $(this).children('td:nth-child(2)').html(fields[$(this).index()]);
        });

        //slide steps
        $('#third_step').slideUp();
        $('#fourth_step').slideDown();            
    });


    $('#submit_fourth').click(function(){

        url =$("input#url").val();
        yourname =$("input#yourname").val();
        email =$("input#email").val();
        phone =$("input#phone").val();

        //send information to server
        var dataString = 'url='+ url + '&yourname=' + yourname + '&email=' + email + '&phone=' + phone;  



        alert (dataString);//return false;  
            $.ajax({  
                type: "POST",  
                url: "http://clients.socialnetworkingsolutions.com/infobox/contact/",  
                data: "url="+url+"&yourname="+yourname+"&email="+email+'&phone=' + phone,
                cache: false,
                success: function(data) {  
                    console.log("form submitted");
                    alert("success");
                }
                });  
        return false;

   });


    //back button
    $('.back').click(function(){
        var container = $(this).parent('div'),
        previous  = container.prev();

        switch(previous.attr('id')) {
            case 'first_step' : $('#progress_text').html('0% Complete');
                  $('#progress').css('width','0px');
                       break;
            case 'second_step': $('#progress_text').html('33% Complete');
                  $('#progress').css('width','113px');
                       break;

            case 'third_step' : $('#progress_text').html('66% Complete');
                  $('#progress').css('width','226px');
                       break;

        default: break;
    }

    $(container).slideUp();
    $(previous).slideDown();
});


});

Источник.

person Community    schedule 09.08.2011

Я бы не рекомендовал использовать для этого регулярное выражение.

Как и в верхнем ответе, удалите все безобразия из номера телефона, чтобы у вас осталась строка числовых символов с 'x', если есть расширения.

В Python:

Примечание. BAD_AREA_CODES взят из текстового файла, который можно получить в Интернете.

BAD_AREA_CODES = open('badareacodes.txt', 'r').read().split('\n')

def is_valid_phone(phone_number, country_code='US'):
    """for now, only US codes are handled"""
    if country_code:
        country_code = country_code.upper()

    #drop everything except 0-9 and 'x'
    phone_number = filter(lambda n: n.isdigit() or n == 'x', phone_number)

    ext = None
    check_ext = phone_number.split('x')
    if len(check_ext) > 1:
        #there's an extension. Check for errors.
        if len(check_ext) > 2:
            return False
        phone_number, ext = check_ext

    #we only accept 10 digit phone numbers.
    if len(phone_number) == 11 and phone_number[0] == '1':
        #international code
        phone_number = phone_number[1:]
    if len(phone_number) != 10:
        return False

    #area_code: XXXxxxxxxx 
    #head:      xxxXXXxxxx
    #tail:      xxxxxxXXXX
    area_code = phone_number[ :3]
    head      = phone_number[3:6]
    tail      = phone_number[6: ]

    if area_code in BAD_AREA_CODES:
        return False
    if head[0] == '1':
        return False
    if head[1:] == '11':
        return False

    #any other ideas?
    return True

Это довольно много. Это не регулярное выражение, но оно довольно легко отображается на другие языки.

person Community    schedule 24.08.2012

Рабочий пример для Турции, просто измените

d{9}

в соответствии с вашими потребностями и начните его использовать.

function validateMobile($phone)
{
    $pattern = "/^(05)\d{9}$/";
    if (!preg_match($pattern, $phone))
    {
        return false;
    }
    return true;
}

$phone = "0532486061";

if(!validateMobile($phone))
{
    echo 'Incorrect Mobile Number!';
}

$phone = "05324860614";
if(validateMobile($phone))
{
    echo 'Correct Mobile Number!';
}
person Community    schedule 19.04.2014

Практически невозможно обрабатывать всевозможные международные телефонные номера с помощью простого регулярного выражения.

Вам было бы лучше использовать такую ​​службу, как numverify.com, они предлагают бесплатный JSON API для проверки международного номера телефона, плюс вы получите полезную информацию о стране, местоположении, операторе связи и типе линии с каждым запросом.

person Community    schedule 03.10.2015

Найдите String regex = "^\\+(?:[0-9] ?){6,14}[0-9]$";

полезно для международных номеров.

person Community    schedule 02.02.2017

Поскольку в этом посте нет языкового тега, я дам решение regex, используемое в python.

Само выражение:

1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+

При использовании в Python:

import re

phonelist ="1-234-567-8901,1-234-567-8901 1234,1-234-567-8901 1234,1 (234) 567-8901,1.234.567.8901,1/234/567/8901,12345678901"

phonenumber = '\n'.join([phone for phone in re.findall(r'1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+' ,phonelist)])
print(phonenumber)

Выход:

1-234-567-8901
1-234-567-8901 1234
1-234-567-8901 1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
person Community    schedule 17.04.2018

Если это вообще возможно, я бы порекомендовал иметь четыре отдельных поля - код города, 3-значный префикс, 4-значная часть, расширение - чтобы пользователь мог вводить каждую часть адреса отдельно, и вы могли проверять каждую часть индивидуально. Таким образом, вы можете не только упростить проверку, но и сохранить свои номера телефонов в базе данных в более согласованном формате.

person Community    schedule 23.09.2008
comment
Однако, если вы решите пойти по этому пути, имейте в виду, что это не сработает за пределами США. Невозможно ввести расширение страны и, например, В Германии есть коды городов переменной длины (от 2 до 4 цифр, плюс начальный ноль, если вы звоните из Германии, который не учитывается, если перед ним указан код страны). - person uliwitness; 01.04.2014

Хотя это не регулярное выражение, вы можете использовать функцию validate_phone() из библиотека Python DataPrep для проверки телефонных номеров в США. Установите его с помощью pip install dataprep.

>>> from dataprep.clean import validate_phone
>>> df = pd.DataFrame({'phone': ['1-234-567-8901', '1-234-567-8901 x1234', 
         '1-234-567-8901 ext1234', '1 (234) 567-8901', '1.234.567.8901',
         '1/234/567/8901', 12345678901, '12345678', '123-456-78987']})
>>> validate_phone(df['phone'])
0     True
1     True
2     True
3     True
4     True
5     True
6     True
7    False
8    False
Name: phone, dtype: bool
person Community    schedule 16.02.2021

Примечание. Он принимает в качестве входных данных номер мобильного телефона в США в любом формате и, при необходимости, может принимать второй параметр - установите значение true, если вы хотите, чтобы выходной номер мобильного телефона выглядел красиво. Если предоставленный номер не является номером мобильного телефона, он просто возвращает false. Если номер мобильного телефона обнаружен, он возвращает весь очищенный номер вместо истины.

    function isValidMobile(num,format) {
        if (!format) format=false
        var m1 = /^(\W|^)[(]{0,1}\d{3}[)]{0,1}[.]{0,1}[\s-]{0,1}\d{3}[\s-]{0,1}[\s.]{0,1}\d{4}(\W|$)/
        if(!m1.test(num)) {
           return false
        }
        num = num.replace(/ /g,'').replace(/\./g,'').replace(/-/g,'').replace(/\(/g,'').replace(/\)/g,'').replace(/\[/g,'').replace(/\]/g,'').replace(/\+/g,'').replace(/\~/g,'').replace(/\{/g,'').replace(/\*/g,'').replace(/\}/g,'')
        if ((num.length < 10) || (num.length > 11) || (num.substring(0,1)=='0') || (num.substring(1,1)=='0') || ((num.length==10)&&(num.substring(0,1)=='1'))||((num.length==11)&&(num.substring(0,1)!='1'))) return false;
        num = (num.length == 11) ? num : ('1' + num);   
        if ((num.length == 11) && (num.substring(0,1) == "1")) {
            if (format===true) {
               return '(' + num.substr(1,3) + ') ' + num.substr(4,3) + '-' + num.substr(7,4)
            } else {
               return num
            }
        } else {
            return false;
        }
    }
person Community    schedule 12.03.2018

Попробуйте это (это для проверки номера мобильного телефона в Индии):

if (!phoneNumber.matches("^[6-9]\\d{9}$")) {
  return false;
} else {
  return true;
}
person Community    schedule 20.03.2018
comment
Почему бы просто не вернуть результат matches? - person nice_dev; 25.01.2019

Java генерирует REGEX для действительных номеров телефонов

Другая альтернатива - позволить Java генерировать REGEX, который отображает все варианты телефонных номеров, считываемых из списка. Это означает, что список с именем validPhoneNumbersFormat, показанный ниже в контексте кода, определяет, какой формат номера телефона является допустимым.

Примечание. Этот тип алгоритма будет работать для любого языка, обрабатывающего регулярные выражения.

Фрагмент кода, генерирующий REGEX:

Set<String> regexSet = uniqueValidPhoneNumbersFormats.stream()
        .map(s -> s.replaceAll("\\+", "\\\\+"))
        .map(s -> s.replaceAll("\\d", "\\\\d"))
        .map(s -> s.replaceAll("\\.", "\\\\."))
        .map(s -> s.replaceAll("([\\(\\)])", "\\\\$1"))
        .collect(Collectors.toSet());

String regex = String.join("|", regexSet);

Фрагмент кода в контексте:

public class TestBench {

    public static void main(String[] args) {
        List<String> validPhoneNumbersFormat = Arrays.asList(
                "1-234-567-8901",
                "1-234-567-8901 x1234",
                "1-234-567-8901 ext1234",
                "1 (234) 567-8901",
                "1.234.567.8901",
                "1/234/567/8901",
                "12345678901",
                "+12345678901",
                "(234) 567-8901 ext. 123",
                "+1 234-567-8901 ext. 123",
                "1 (234) 567-8901 ext. 123",
                "00 1 234-567-8901 ext. 123",
                "+210-998-234-01234",
                "210-998-234-01234",
                "+21099823401234",
                "+210-(998)-(234)-(01234)",
                "(+351) 282 43 50 50",
                "90191919908",
                "555-8909",
                "001 6867684",
                "001 6867684x1",
                "1 (234) 567-8901",
                "1-234-567-8901 x1234",
                "1-234-567-8901 ext1234",
                "1-234 567.89/01 ext.1234",
                "1(234)5678901x1234",
                "(123)8575973",
                "(0055)(123)8575973"
        );

        Set<String> uniqueValidPhoneNumbersFormats = new LinkedHashSet<>(validPhoneNumbersFormat);

        List<String> invalidPhoneNumbers = Arrays.asList(
                "+210-99A-234-01234",       // FAIL
                "+210-999-234-0\"\"234",    // FAIL
                "+210-999-234-02;4",        // FAIL
                "-210+998-234-01234",       // FAIL
                "+210-998)-(234-(01234"     // FAIL
        );
        List<String> invalidAndValidPhoneNumbers = new ArrayList<>();
        invalidAndValidPhoneNumbers.addAll(invalidPhoneNumbers);
        invalidAndValidPhoneNumbers.addAll(uniqueValidPhoneNumbersFormats);

        Set<String> regexSet = uniqueValidPhoneNumbersFormats.stream()
                .map(s -> s.replaceAll("\\+", "\\\\+"))
                .map(s -> s.replaceAll("\\d", "\\\\d"))
                .map(s -> s.replaceAll("\\.", "\\\\."))
                .map(s -> s.replaceAll("([\\(\\)])", "\\\\$1"))
                .collect(Collectors.toSet());

        String regex = String.join("|", regexSet);

        List<String> result = new ArrayList<>();
        Pattern pattern = Pattern.compile(regex);
        for (String phoneNumber : invalidAndValidPhoneNumbers) {
            Matcher matcher = pattern.matcher(phoneNumber);
            if(matcher.matches()) {
                result.add(matcher.group());
            }
        }

        // Output:
        if(uniqueValidPhoneNumbersFormats.size() == result.size()) {
            System.out.println("All valid numbers was matched!\n");
        }    
        result.forEach(System.out::println); 
    }

}

Вывод:

All valid numbers was matched!

1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
...
...
...
person Community    schedule 07.09.2020

поскольку существует так много вариантов записи номера телефона, можно просто проверить, достаточно ли в нем цифр, независимо от того, как они разделены. Я обнаружил, что для меня работают от 9 до 14 цифр:

^\D*(\d\D*){9,14}$

правда:

  • 123456789
  • 1234567890123
  • +123 (456) 78.90-98.76

ложный:

  • 123
  • (1234) 1234
  • 9007199254740991
  • 123 не буду делать то, что ты мне говоришь
  • +123 (456) 78.90-98.76 # 543 доб 210 ›2› 5 ›3
  • (123) 456-7890 утром (987) 54-3210 после 18:00 и спросить Ширли

если вы действительно хотите поддержать эти два последних примера, просто удалите верхний предел:

(\d\D*){9,}

(^$ не нужны, если нет верхнего предела)

person Community    schedule 11.08.2020