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

920

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

  • 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

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

Nicholas Trandem
источник
3
Кстати, вы должны указать, какой язык вы используете. Не все движки регулярных выражений имеют одинаковый синтаксис.
AndrewJFord
9
Похоже, вы пропустили вариант +1 вместо просто 1, хотя ответ охватывает этот случай.
Эрик
153
Разве все номера телефонов США не требуют 555в них, кроме 911?
Эндрю Гримм
41
Напротив, префикс 555 зарезервирован для поддельных телефонных номеров. Эти номера гарантированно не подключаются к реальному номеру телефона, поэтому они часто используются на телевидении и в фильмах, чтобы зрители не пытались набрать номер и в конечном итоге преследовали бедного невиновного.
rushinge
49
@rushinge Хотя это было верно десятилетия назад, это уже не так . Префикс 555 по-прежнему особенный, но гарантированно завершится только небольшой диапазон номеров без соединения с 555-0100 по 555-0199. Но я почти уверен, что Эндрю все равно пошутил.
Адам Дэвис

Ответы:

515

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

Затем вы получите такие значения, как:

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

Затем, когда вы показываете, переформатировать в свое содержание сердца. например

  1 (234) 567-8901
  1 (234) 567-8901 x1234
scunliffe
источник
35
Код форматирования будет пустой тратой времени, если номера будут приходить из-за пределов США.
Даниэль Уорвикер
26
Это хорошо, и все, но это не подтверждает, что на самом деле был введен номер телефона. Например, что если пользователь не введет необходимые 10 цифр? Это должно сочетаться с хорошей проверкой регулярных выражений.
Хью Джеффнер
108
Учитывая вопрос был о проверке - это действительно очень плохой ответ.
PlexQ
15
@PlexQ Я не согласен. Первоначальная проблема - попытка обработать проверку номера телефона, потому что она пыталась обработать все возможные варианты форматирования. Вместо того, чтобы пытаться решить все это, возьмите входные данные и «предварительно удалите» все пух форматирования, пока у вас не будет только «числа». Это решает 2 проблемы - тестирование результата теперь легко, и теперь вы можете гарантировать, что все значения, возвращаемые для отображения, могут быть отформатированы согласованно. Первый комментарий к этому ответу о «Перчатках усложнителя» - это хорошее прочтение ... иногда ответом на проблему является подход к нему по-другому.
Scunliffe
29
Как, черт возьми, это такой высоко оцененный ответ? Это ничего не подтверждает . Что еще хуже, все остальные вопросы проверки телефонных номеров ссылаются на этот ...
jlars62
303

Оказывается, есть что-то особенное для этого, по крайней мере для Северной Америки, под названием 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+))?$
оборота fatcat1111
источник
7
здесь это без секции расширения (я заставляю моих пользователей вводить 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}) $
aarona
18
Вот версия, которая соответствует только 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})/
Brian Armstrong
8
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})
Брук.
5
@StevenSoroka В течение последних двух лет у меня на столе лежала книга Джеффри Фридла, так как регулярные выражения являются основной частью моей работы. Требуется много времени, чтобы по-настоящему понять регулярные выражения. Иногда читатели этого сайта просто ищут существующее решение, а не пишут свое собственное, особенно в доменах с множеством угловых случаев, таких как представления телефонных номеров.
Джастин Р.
7
@ fatcat1111 Я понимаю это, но большинство ответов здесь - это одноразовые регулярные выражения типа «я тоже», которые, вероятно, не подходят ни для одного из ваших угловых случаев. Затем они оказываются на всех веб-сайтах, которые я пытаюсь использовать, и я не могу ввести свой почтовый индекс, номер телефона или адрес электронной почты, потому что кто-то использовал недоделанное регулярное выражение (например: + является допустимым символом в адресах электронной почты ). Лучшие ответы на этой странице указывают пользователям на библиотеки, а не на регулярные выражения, написанные на салфетках.
Стивен Сорока
298
.*

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

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

"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"
Дейв Кирби
источник
202
Я согласен с мнением здесь, но иногда приятно проводить проверку, когда телефонный номер фактически будет использоваться для чего-то важного в интересах пользователя . Лучший пример здесь - авторизация кредитной карты для покупки. Если номер телефона указан неверно, аутентификация может быть неудачной.
Заостренный
53
Если пользователь не хочет вводить свой номер телефона, вы можете просто оставить поле необязательным, но стоит ли просить пользователя ввести действительный номер телефона, если он собирается его ввести?
Джоэл МакБет
11
Кроме того, роль валидации заключается в том, чтобы просто напомнить людям о необходимости добавления кодов городов и т. Д., Которые они, в противном случае, не могли бы добавить, но о которых невозможно догадаться после факта.
Бен Макинтайр
29
@Pointy Но проверка регулярных выражений не поможет вам. Единственный способ проверить правильность номера телефона - это отправить ему сообщение (в случае мобильного телефона) И убедиться, что пользователь подтверждает использование какого-либо кода подтверждения. Это то, что вы делаете, когда важна правильность числа. Все остальное только для удобства пользователя защищает от некоторых (но не от всех) опечаток и ничего не проверяет.
Алекс Б
14
Круто. Мой номер телефона 1 'ИЛИ 1 = 1 - PWNED . См. Xkcd.com/327 и owasp.org/index.php/Testing_for_SQL_Injection_(OWASP-DV-005)
Аарон Ньютон,
171

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

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

15555555555

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

Основные функциональные возможности:

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

Примеры

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

  • Америка
    • (408) 974–2042является действительным номером США
    • (999) 974–2042это не является допустимым количество США
  • Австралия
    • 0404 999 999является действительным австралийский номер
    • (02) 9999 9999также действительный австралийский номер
    • (09) 9999 9999это не является допустимым австралийский номер

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

Я бы предложил пропустить простое регулярное выражение для проверки вашего телефонного номера и использовать такую ​​библиотеку, как Google 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(международная версия (02) 9999 9999), возвращает в качестве действительного числа с форматированием:

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 для проверки и отображения телефонных номеров.

Tim Groeneveld
источник
Отмечая, что теперь есть также порт Go по адресу: github.com/ttacon/libphonenumber
michaelhanson,
При проверке, возможно ли это число, вам не нужно указывать код страны? Я использую версию PHP, и если я ввожу британское число вроде (замените 0 действительными числами), 07700000000я получаю Missing or invalid default region.ошибку. Но если я укажу код страны, он пройдет.
BugHunterUK
К вашему сведению: эта библиотека не поддерживает некоторые страны, phpinterviewquestions.co.in/blog/ionic/…
sijo vijayan,
1
@BugHunterUK (и любой, кто сталкивается с этим вопросом и интересуется тем же), анализируя число, вы можете указать ожидаемый регион, и библиотека будет искать немеждународные номера в этом регионе. Если вы не укажете, он отклонит что-либо не в допустимом международном формате.
IMSoP
Рассмотрим github.com/nyaruka/phonenumbers, поскольку он стал "официальным" пакетом Go, рекомендованным Google, а не libphonenumber.
DeeZone
78

/^(?:(?:\(?(?: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

Ismael Miguel
источник
Это было наиболее полное регулярное выражение, которое я видел. Это легко обойти , пока вы не удалите ^и $или иначе я смог обойти его , используя [111] [111] [1111]или 111--111--1111и тому подобное. (извините, удалил мой последний комментарий)
bafromca
Не могли бы вы перефразировать? Я не могу понять это: «Легко обойтись, пока вы не удалите ^ и $, иначе я не смогу обойти это, используя [111] [111] [1111]». Означает ли это, что он проверяет «[111] [111] [1111]», когда вы берете ^и $?
Исмаэль Мигель
Я обошел ваше регулярное выражение, используя [111] [111] [1111]и 111--111--1111пока я не удалил ^и $из регулярного выражения.
Bafromca
11
^^^ Это отличный пример того, почему темы комментариев НЕ должны переходить в чат. Мне очень интересно, как получился этот разговор, и мне нужно знать, достаточно ли надежен этот ReGex для использования в моем приложении. К сожалению, разговор в чате сейчас ушел.
Мэтт Кашатт
1
Честно говоря, я не пошел в чат. Спросив несколько раз для объяснений, я остался без информации. Вы всегда можете попробовать это самостоятельно со всеми видами чисел, которые вы найдете в Интернете, в нескольких форматах. Одна вещь, которую я попробовал с этим, состоит в том, чтобы использовать многократные телефонные номера, но это не работает так хорошо, если у них есть пробелы вокруг. И я должен найти решение, чтобы посчитать количество цифр и обеспечить конкретное количество.
Исмаэль Мигель
63

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

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*))?';
Индив.
источник
2
К вашему сведению, регулярное выражение также соответствует: (4570457-6789это было бы довольно распространенной опечаткой. Матчевые
SooDesuNe
@SooDesuNe Предоплата (^|[^\d\n])(с включенным многострочным флагом) позволяет избежать общей проблемы, гарантируя, что ей не предшествует что-то числовое.
btown
Обратите внимание, что это в Северной Америке - он пропускает "44 7911 123456"
Бен Уилер
43

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

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

Быстрый шпаргалка

  • Запустите выражение: /^
  • Если вы хотите использовать пробел, используйте: [\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.
  • $/ : Конец выражения
vapcguy
источник
1
Это очень полезно, но я сомневаюсь и ищу выражение {min, max}. Вы можете помочь?
Атабой Йозеф
Если речь идет об одной цифре (и вы можете сделать так, чтобы она соответствовала этому), посмотрите [2-9]блок, который я поставил там. Это означает, что ваш минимум равен 2, а ваш максимум равен 9. Отрегулируйте соответственно.
vapcguy
30

Я написал самое простое (хотя мне не нужна точка в нем).

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

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

Артём Курапов
источник
38
это проверяет тонны чисел, которые технически недействительны. как, "- + () () ()) ())))". Научитесь читать регулярные выражения, чтобы вы могли понять, что вы делаете.
Стивен Сорока
3
Технически @StevenSoroka может допускать множество недопустимых случаев, но когда мы думаем о том, чтобы просто помочь пользователю избежать распространенных ошибок с помощью самого простого из возможных решений, это путь :)
happyhardik
2
это также соответствует пустому пространству, пустой строке
Васим А.
1
@HappyHardik. Верно. Простой и мощный инструмент для базовой проверки позволяет пользователю вводить более одной точки, тире, скобки или плюс.
dijipiji
Просто использовал это, и это неправильно во многих аспектах. Например, номер телефона в Великобритании может начинаться с +44, или внутри номера телефона может быть (0). Но это недействительно согласно вашему регулярному выражению. Я бы порекомендовал ответ @Ismael Miguel. Это работает просто отлично, и я бы порекомендовал вам пересмотреть свой ответ.
Стелиос Воскос
22

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

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

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

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

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

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

Стив
источник
22

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

Ben Clifford
источник
15

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

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

Роб Уэллс
источник
3
Это выглядит как отличный способ интегрировать неясные ошибки в ваш код.
Том Лорд
12

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

/^[+#*\(\)\[\]]*([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

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

ReactiveRaven
источник
12

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

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

Herobrine2Nether
источник
11

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

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

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

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

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

ron0
источник
Я пытался реализовать вышеизложенное в моем сценарии проверки JavaScript, но получаю сообщение invalid quantifierоб ошибке. Есть идеи, что я делаю не так?
Яннис
Я бы добавил тривиальный случай, когда телефон указан без символов, но, возможно, пробелы и код страны, в Европе типично для местных и мобильных номеров: 676412342, 676 46 32 12, 676 463 212
rupps
11

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

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

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

Стюарт Кершоу
источник
Это имеет ограниченную поддержку расширений. Он соответствует «616-555-1234 x567», но не «616-555-1234 доб. 567».
Джон Шнайдер
2
Неверно положительный, например, "------- (((((55555555" или "99999999999999999999999"
mikep
Это не подтверждает число макдональдсов в Нитерленде +31 76 596 4192 (я только что проверял случайные числа)
BIOHAZARD
10

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

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

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

mindplay.dk
источник
Попробовав несколько из них и изучив имеющиеся данные и отзывы пользователей, я склонен согласиться ...
Кристофер Кинг
Иногда вам нужно сделать проверку, хотя. Если я отправляю коды подтверждения, я не могу просто отправить код для любого случайного мусора, который спамер вводит в поле. Я хочу убедиться, что этот номер, вероятно, номер телефона, прежде чем тратить ресурсы на обмен сообщениями.
Лука
10

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

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

GaiusSensei
источник
Спасибо. Как насчет стационарных номеров с кодом города, например 028231234? Мне интересно, если коды городов состоят только из 2-3 цифр и им всегда предшествует 0?
stormwild
9

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

^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$
Николас Трандем
источник
9

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

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

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

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

-Адам

Адам Дэвис
источник
Не предлагаемое решение. ЭТО ВОЗМОЖНО. То, что это сложно или сложно, не означает, что вы должны просто поднять руки вверх.
Эрик Ходонский
7

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

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

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

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;
}
Дрю Томас
источник
Это регулярное выражение соответствует +1 1234562222222222222222222222.
Варда Элентари
почему бы просто не вернуться?
thexande
Ложное срабатывание для «999999999999999999999999999999999999999»
Бен Уилер
6

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

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

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

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

Джон Эриксон
источник
Я собираюсь выйти из этого положения и сказать, что использование 911 в качестве номера телефона, вероятно, является плохой идеей почти во всех приложениях этого регулярного выражения. Хороший улов, хотя.
Николас Флинт
4

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

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

Джо Филлипс
источник
Проверка? 123% $) *% () $ * () # 456 * () * $ # (* (# $ @ 8908 будет соответствовать предложенному вами решению.
PlexQ
1
@PlexQ 555-123-1234, 07777777777, 90210, 01.01.1901 - пользователи изобретательны в том, чтобы утрамбовывать мусор посредством проверки. Лучше не ставить галочку на тех, кто действительно имеет какие-то странные данные, используя чрезмерно ограничительную проверку и сообщая им, что они ошибаются.
ReactiveRaven
4

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

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

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

rooskie
источник
3

Я нашел это что-то интересное. Я не проверял это, но похоже, что это будет работать

<?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.';
}
?>
Крис
источник
4
Ваше сообщение указывает на то, что вы не написали этот код. Не могли бы вы привести источник, пожалуйста?
Аластер Ирвин
bitrepository.com/how-to-validate-a-telephone-number.html выглядит как источник.
Джеймс Патерсон
3

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

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

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

Абе Мисслер
источник
3

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

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

"^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$"
Ричард Айотт
источник
3

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

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

\d+ ?\w{0,9} ?\d+
  • 01234467 extension 123456
  • 01234567x123456
  • 01234567890
Keith Wiggans
источник
2

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

Пара простых выражений Perl может быть:

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

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

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

piCookie
источник
2
    pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" 
    validateat="onsubmit"

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

Ян
источник
2

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

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();
});


});

Источник .

Lajos Arpad
источник