Regex работает неправильно, сопоставляя неожиданные вещи

У меня есть это регулярное выражение:

[\(\+\[]?[0-9]([\-\)\.\/-\]]?\s?\(?[0-9\s\)]){8,20}?

Он должен соответствовать только телефонным номерам, но вместо этого он также соответствует таким вещам, как:

[95.86.22.137]
95.86.22.137
(192.168.1.94)
274.1363525390625px;">
2014-8-720:32:45

Может кто-нибудь помочь мне исправить это регулярное выражение?

Ответ 1

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

Вы должны сначала решить, что вы примете, как "действительный номер телефона". Помните, что даже в NANP (Североамериканский план нумерации) есть несколько разных форматов:

  • XXX-XXX-XXXX или
  • XXX XXX-XXXX или
  • 1-XXX-XXX-XXXX или
  • (XXX) XXX-XXXX или
  • + (XXX) XXX-XXXX или
  • 1 (XXX) XXX-XXXX

И все они являются допустимыми числами, поэтому вам нужно будет выбрать формат, который вы примете. И тогда есть разные форматы во всем остальном мире различной длины от 9 (Португалия) до 13 (Южная Корея) цифр, включая код страны и международного кода. Поэтому вам нужно решить:

  • Будете ли вы принимать только номера NANP или другие номера за пределами этого стандарта?
  • Будете ли вы принимать "+" или заставлять их писать международный код? Будет ли код для стран, в которые будет вводиться ваш пользователь, имеет заданное количество цифр, если вам нужен код? Если они вводят код, ваше регулярное выражение сможет обрабатывать (если это приемлемо) или красный флаг (если это неприемлемо), что?
  • Вы скопируете скобки вокруг кода области, просто разрешите им (сделайте скобки необязательными) или прямо откажитесь от них?

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

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

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

Но мне было ужасно недоставать в том, как делать человека "+" против "1" и пробелом (для номеров NANP), как применять скобки, дефисы и т.д. Это дает вам регулярные выражения а не объяснять, как доставить вас туда. Отсюда мой "блог", здесь, для ответа.

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

  • + (XXX) XXX-XXXX
  • 1 (XXX) XXX-XXXX
  • (XXX) XXX-XXXX

Он требует скобок и дефис, что, по моему мнению, для чисел NANP дает большую гибкость при соблюдении стандарта. К сожалению, я не занимаюсь международными (за пределами NANP) номерами:

/^(\+|1\s)?[(][2-9]\d{2}[)][\s][2-9]\d{2}-\d{4}$/

/^= совпадение в начале слова; в основном просто указывает начало выражения

(\ + | 1\S)? группа

  • Скобки скобки используются для смещения группы и говорят, что любой из символов внутри не является обязательным, через ? в конце и разрешать внутри или внутри условия (см. символ канала)
  • \+= Сбежал "+", чтобы разрешить сопоставление на знаке плюса (должен быть экранирован, поскольку он является ключевым символом в регулярном выражении, используя обратную косую черту)
  • |= символ трубы, чтобы сказать, что он должен совпадать либо с левым, либо с правым, внутри группы
  • 1\s= Требуется номер 1 и пробел. Пространство не требуется для [] - это не сработало для меня, хотя я видел другие сообщения, которые, похоже, указывают на это. Это \s.

[(]= Вот как вы указываете, что требуется открытая скобка.

[2-9]\d {2} группа

  • [2-9]= Это означает, что выражение соответствует цифре 2-9. Это связано с тем, что в NANP 0 и 1 являются недопустимыми числами в начале кода области (первый набор из 3 чисел) или в телефонной станции (второй набор из 3 цифр).
  • \d{2}= Это говорит, чтобы разрешить 2 цифры от 0 до 9. Это сокращение для [0-9][0-9].

Для трехзначной группы от 000-999 вы просто скажете: \d{3}

[)]= Вот как вы указываете, что требуется закрытая скобка.

[\s]= Для этого потребуется пробел.

[2-9]\d {2} -\d {4} группа

  • Эта первая часть перед дефисом аналогична предыдущей.
  • Здесь нужно установить дефис. Если вы поместите -?, это будет необязательно.
  • \d{4}= Это говорит о том, чтобы разрешить 4 цифры от 0 до 9. Это сокращение для [0-9][0-9][0-9][0-9]

$/= Говорит, что соответствует концу слова; в основном просто указывает конец выражения.

Надеюсь, это поможет вам создать свое выражение.