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

yok

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

Казалось бы что проще проверить телефон, уточняю корректность ввода.
Телефоны могут быть 8 (961) 56 45 324 и 211-30-42
С первой составляющей 8 (ххх) просто а вот 322 34 44
тут как то не получается.
ясно что только из \s и \d
[\s\d]+ это чтотто не очень корректно 3453 234523 34253 3443 345
привязывать к конкретно количеству цифр хотелось бы. Компоновка их не актуальна там допустим 23 333 22 или 233 11 11 или 2221111
[(\s)*(\d)]{4,9}$, попытался вот такое да работает и на ура, (да оговорюсь множественные пробелы предварительно уберем), работает только вот только на превышение символов, там 10 уже не пропускает, а один проходит тоже, как же с минимальным количеством???
подождите, появились мысли. Надо подумать.
Буду рад услышать Ваши мысли и решения. и соображения.
Всем удачи.

-~{}~ 21.10.09 16:18:

Вообще конечно сивмольный клас в множественный квантификатор это я загнул.
 

dimagolov

Новичок
yok, а на сколько критично, чтобы номера были корректные? если очень, то надо смотреть номерной план телекома, чтобы добиться какой-то реалистичности и не забыть про международную нумерацию.
если не очень, то забей. есть цифры, и хорошо. потому что туда могут писать 533-56-78 ext 25 и т.п.
 

yok

Новичок
dimagolov , корректность, чтоб цифры только и из количество чтоб не 20 цифр и не 5. В принцыпе я решил задачу. Только про цыфры и (861) скобки, но думаю надо еще пропустить - 23-34-42 тире.
/^\d(?:\s)*(?:(?:\()?(?:\d){3,4}(?:\))?)*(?:\s)*\d[(\s)*(\d)+]{4,7}\d$/
в скобка может быть 3 или 4, у нас в крае есть, да оговорюсь, расчитано на край, там ext 23, это уже думаю лишне, после скобок, необязательный пропуск, потом обязательная цифра, и символьный клас, блин множественный квантификатор работает для символьного класса, как не странно, нигде не видел о такой конструкции, ни в jeff friedl, но работает и на минимальные, ну и последняя цыфра, правда если trim то может и не надо, не погружался в раздумья.
Есть улучшения кода и соображения?
Всем спасибо.

-~{}~ 22.10.09 10:09:

чет голова какая то пролезла, там двоеточие и скобки, а это интерпретация двоеточия и скобок открывающих.

-~{}~ 22.10.09 12:37:

вобще то эта конструкция \d[(\s)*(\d)+]{4,7}\d плоха, она конечно работает, правда приблизительно, и думаю этого достаточно для определенной корректности, но не как математический шаблон.
я и так и так не получается \d([\s*\d]){1,7}\d
Все оказалось еще проще \d(?:\s*\d){3,5}\d
и теперь и для таких 8(9883)2323432 и для 2322332, вобщем семизначные после скобок, и можно 5значные, у нас в области есть .
Если есть улечшения буду рад увидить .
Спасибо.
 

dimagolov

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

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

phprus

Moderator
Команда форума
По нормальному надо чистить из номера все не цифры, проверять его длину и существование кода страны/города/сотового оператора( по вкусу)

Регулярное выражение Применять крайне не рекомендуется.
Реализовывал как огромный костыль для временной подпорки реализации.
Проверяет номер с указанием кода страны вида +КОДСТРАНЫ хххххххххх
PHP:
$re = '/^\+(1|20|210|211|212|213|214|215|216|217|218|219|220|221|222|223|224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|240|241|242|243|244|245|246|247|248|249|250|251|252|253|254|255|256|257|258|259|260|261|262|263|264|265|266|267|268|269|27|28|290|291|292|293|294|295|296|297|298|299|30|31|32|33|34|350|351|352|353|354|355|356|357|358|359|36|370|371|372|373|374|375|376|377|378|379|380|381|382|383|384|385|386|387|388|389|39|40|41|420|421|422|423|424|425|426|427|428|429|43|44|45|46|47|48|49|500|501|502|503|504|505|506|507|508|509|51|52|53|54|55|56|57|58|590|591|592|593|594|595|596|597|598|599|60|61|62|63|64|65|66|670|671|672|673|674|675|676|677|678|679|680|681|682|683|684|685|686|687|688|689|690|691|692|693|694|695|696|697|698|699|7|800|801|802|803|804|805|806|807|808|809|81|82|83|84|850|851|852|853|854|855|856|857|858|859|86|870|871|872|873|874|875|876|877|878|879|880|881|882|883|884|885|886|887|888|889|89|90|91|92|93|94|95|960|961|962|963|964|965|966|967|968|969|970|971|972|973|974|975|976|977|978|979|98|990|991|992|993|994|995|996|997|998|999)\s*(?:(?:\(\s*(?:(?:(\d{1})\s*\)\s*(\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d))|(?:(\d{2})\s*\)\s*(\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d))|(?:(\d{3})\s*\)\s*(\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d))|(?:(\d{4})\s*\)\s*(\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d))|(?:(\d{5})\s*\)\s*(\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d))|(?:(\d{6})\s*\)\s*(\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d))|(?:(\d{7})\s*\)\s*(\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d))|(?:(\d{8})\s*\)\s*(\d(?:\s*-?\s*)\d))))|((?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d(?:\s*-?\s*)\d))$/';
В качестве разделителей групп цифр допускаются пробелы и -, код страны может быть заключен в скобки
 

yok

Новичок
phprus, привет, спасибо за мысли.
Для начала скажу что уточнение хорошее, +7, я не подумал об этом, конечно у меня только для россии, значит только 8 можно оттолкнуться. Об этом стоит подумать.
Проверил твое выражение, но оно не работает с $tel="8(9842)2334433";
и так 8-(9842)233-44-33 и так 8-(984)233-44-33
сейчас посмотрю повнимательней, но увы.

-~{}~ 23.10.09 11:11:

phprus, ты проверял этот код, я в начале вижу что, сначала код страны, так, далее (?:\(\s*(?:(?:(\d{1})\s*\) вот ты проэкранировал что в скобках., а ясно ты или, но зачем тогда их до {8}, потом окончательное или 10 цифр, посчитаем
8 981 2113454 , да подходит, но вот тебе телефон 211 2333
а вот другой, 8(4234)33 332 это такие по области есть,
спасибо за направление алгоритма.
Вот алгоритм который учитывает эти особенности, только без направления +7 а просто 8 (422) xxxx-xxx or xxx-xx-xx ,
вобщем на данном этапе поиска все, но сами понимаете что пути господни неисповедимы.
/^\d(?дв(?:)?(?:\s)?){0,2}(?дв(?:\()?(?:\d){3,4}(?:\))?)*(?:(?:)?(?:\s)?){0,2}\d(?:(?:)?\s*\d){3,5}\d$/
и выражение достаточто маленькое.
Да после интерпретации форум изменит думаю счас увидим.
Точно, даже не пропустил, где дв это двоеточие

-~{}~ 23.10.09 11:12:

слишком много писал смайликов, и две прошло, где морда там двоеточие и открывающие скобки.

-~{}~ 23.10.09 11:16:

ой простите где дв это двоетоичие и открыающая скобка
Спасибо за мысли .

-~{}~ 23.10.09 11:38:

phprus
Регулярное выражение Применять крайне не рекомендуется.
это ты о своем выражении? если нет, то читал обратное утверждение.
К тому же код страны можно компактно сделать и в добавок к моему выражение получиться очень маленьким .
И думаю тогда это не костыл, а именно регулярное выражение.
 

phprus

Moderator
Команда форума
yok
Регулярное выражение Применять крайне не рекомендуется.
это ты о своем выражении? если нет, то читал обратное утверждение.
Это я о своем регулярном выражении, потому, что только с помощью регулярных выражений эту задачу корректно НЕ решить, а если и решить то цена поддержки этого решения будет велика.

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

yok

Новичок
phprus вот это выражение все и решает
/^\d(?дв(?:)?(?:\s)?){0,2}(?дв(?:\()?(?:\d){3,4}(?:\))?)*(?дв?:)?(?:\s)?){0,2}\d(?дв?:)?\s*\d){3,5}\d$/
где дв там двоеточие и открывающая скобка.
Если есть улучшения, очень буду рад увидить.
Спасибо.
 
Сверху