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


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

  • 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

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

30 836

30 ответов:

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

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

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

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

  1 (234) 567-8901
  1 (234) 567-8901 x1234

оказывается, для этого есть что-то вроде спецификации, по крайней мере для Северной Америки, называемой 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+))?$
.*

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

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

"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"

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

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

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

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

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

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 [--]\n" if not defined ;
                print "match [-- ]\n" if defined ;
        }
        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   \n";
        }
}

Edit:

вы можете изменить \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*))?';

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

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

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

  • начать выражение: /^
  • Если вам требуется место, используйте: [\s] или \s
  • если вы хотите требовать скобки, используйте: [(] и [)] . Используя \( и \) уродливо и может сделать вещи запутанными.
  • если вы хотите, чтобы что-то было необязательным, поставьте ? после
  • если вы хотите дефис, просто типа - или [-] . Если вы не ставите его первым или последним в ряду других символов, хотя, возможно, вам придется избежать его:\-
  • если вы хотите принять различные варианты в слот, заключить в скобки вариантов: [-.\s] потребуется дефис, точка или пространство. Вопросительный знак после последней скобки сделает все это необязательным для этого слота.
  • \d{3}: требуется 3-значный номер: 000-999. Стенография для [0-9][0-9][0-9].
  • [2-9]: требуется цифра 2-9 для этого слота.
  • (\+|1\s)?: примите "плюс" или 1 и Пробел (символ трубы, |, "или"), и сделать его необязательным. Знак "плюс" должен быть экранирован.
  • если вы хотите, чтобы определенные номера соответствовали слоту, введите их: [246] потребуется 2, 4, или 6. [77|78] потребуется 77 или 78.
  • $/ : конечное выражение

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

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

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

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

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

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

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

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

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

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

вы уже посмотрели на RegExLib?

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

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

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

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

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

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

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

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

моя попытка безудержного регулярного выражения:

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

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

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

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

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

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

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

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

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

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

Адам

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

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

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

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

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

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

function phoneToTel($number) {
    $return = preg_replace('/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/', '<a href="tel:"> () -</a>', $number); // includes international
    return $return;
}

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

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

/^\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-яблоко

первоисточник:http://www.regexr.com/38pvb

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

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

Я считаю номер:: телефон:: US и Регулярное Выражение:: Common (особенно источник регулярное выражение:: Common:: URI:: RFC2806) модули Perl могут помочь.

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

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

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

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

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

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

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

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

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

<?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.';
}
?>

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

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

Они даже идут над тем, как замаскировать ввод номера телефона в своем учебнике.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 по этой ссылке.

EDIT:

решение 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();
});


});

источник.