Комплексное регулярное выражение для проверки номера телефона - PullRequest
874 голосов
/ 24 сентября 2008

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

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

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

Ответы [ 39 ]

15 голосов
/ 24 сентября 2008

Вы смотрели на RegExLib ?

Ввод номера телефона в США привел довольно много возможностей.

12 голосов
/ 09 марта 2012

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

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

Принимает:

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

Rejects:

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

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

12 голосов
/ 12 сентября 2015

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

^\(*\+*[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

11 голосов
/ 10 апреля 2009

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

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

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

^((((\(\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

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

10 голосов
/ 18 января 2012

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

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

или

((\+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

10 голосов
/ 15 апреля 2011

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

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

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

9 голосов
/ 24 сентября 2008

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

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

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

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

-Adam

9 голосов
/ 24 апреля 2015

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

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

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

Positive:
+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

Negative:
926 3 4
8 800 600-APPLE

Оригинальный источник: http://www.regexr.com/38pvb

8 голосов
/ 08 июля 2014

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

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

Пока что он работает со всем, что им на это брошено, но если появятся ошибки, я обновлю этот ответ.

Regex:

/(\+*\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;
}
8 голосов
/ 24 сентября 2008

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

^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$
...