Скажу честно, когда я впервые увидел регулярное выражение, это был пугающий опыт. Это похоже на странный инопланетный язык! Я подумал про себя: "Я потратил месяцы на изучение программирования, и теперь я должен выучить этот, казалось бы, сверхсложный язык!?"

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

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

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

Я научу вас проверять номер телефона одной строкой кода и одним регулярным выражением. **Проверка номера телефона БЕЗ регулярных выражений становится неприятным вопросом leetcode. ** 😧

Почему так сложно проверить номер телефона?

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

Все это ДЕЙСТВИТЕЛЬНЫЕ номера для США:

  • 202-515-5555
  • 202 515 5555
  • (202)515 5555
  • 1 202 515 5555
  • 2025155555
  • 1-202-515-5555
  • 1202-515-5555
  • etc

Есть более допустимые комбинации, которые я не перечислил, но вы поняли идею! Проверка каждой комбинации, потому что это неприятная проблема с кодированием. _Но НЕ, если вы используете регулярное выражение для его проверки! _ 😉

Начнем с самого простого случая

Давайте сначала проверим 202-515-5555. Основная идея регулярного выражения состоит в том, чтобы создать шаблон, соответствующий строке. Какова закономерность в 202-515-5555 ?

Мы начинаем с 3 цифр, за которыми следует -, затем еще 3 цифры, за которыми следует еще одна -, затем мы заканчиваем 4 цифрами.

Вот как выглядит шаблон регулярного выражения для соответствия 202-515-5555:

^\d{3}-\d{3}-\d{4}$

Давайте посмотрим через это…

^ просто указывает на начало строки. В приведенном выше регулярном выражении мы указываем, что номер телефона должен начинаться с \d{3}, так как у нас есть ^ перед \d{3}.

Теперь \d => обозначает одну цифру, а {3} simple означает, что \d повторяется ровно 3 раза. Таким образом, ^\d{3} означает, что наш номер телефона НАЧИНАЕТСЯ с 3 цифр.

Теперь давайте просто перейдем к концу: $ указывает на конец совпадения строки. \d{4}$ означает, что наш номер телефона должен заканчиваться четырьмя цифрами. Имеет ли это смысл?

- просто означает, что номер телефона должен иметь дефис в этом месте.

Итак, давайте теперь прочитаем все регулярное выражение слева направо:

  1. ^\d{3} ⇾ начните с 3 цифр
  2. - ⇾ затем тире
  3. \d{3} ⇾ с последующими 3 цифрами
  4. - ⇾ затем тире
  5. \d{4}$ ⇾ заканчивается 4 цифрами

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

Как мне сопоставить номер телефона, если тире являются вариантами?

Отличный вопрос! Как нам сопоставить ОБА: 202-515-5555 и 2025155555

Чтобы сделать совпадение символов необязательным, просто добавьте после него ?.

Вот как выглядит наше новое улучшенное соответствие:

^\d{3}-?\d{3}-?\d{4}$

-? просто означает, что - является необязательным: он может быть, а может и не быть!

Давайте еще раз прочитаем все регулярное выражение:

  1. ^\d{3} ⇾ начните с 3 цифр
  2. -?необязательно с дефисом
  3. \d{3} ⇾ затем 3 цифры
  4. -?необязательно с дефисом
  5. \d{4}$ ⇾ заканчивается на 4 цифры

Как насчет сопоставления номера телефона, если вместо тире есть пробелы?

Теперь давайте поработаем над сопоставлением: 202-515-5555, 2025155555 и 202 515 5555.

Вместо того, чтобы просто иметь -, мы можем дополнительно иметь либо -, либо . Как мы это представляем? Просто поместите - и внутри [...] вот так: [ -].

Наше новое регулярное выражение выглядит так:

^\d{3}[ -]?\d{3}[ -]?\d{4}$

Теперь это определенно начинает выглядеть инопланетянином! 😅

Давайте разберем это:

  1. ^\d{3} ⇾ начните с 3 цифр
  2. [ -]?необязательно с последующим пробелом ИЛИ тире
  3. \d{3} ⇾ с последующими 3 цифрами
  4. [ -]?необязательно с последующим пробелом ИЛИ тире
  5. \d{4}$ ⇾ заканчивается 4 цифрами

Как сопоставить 1 или 1 или 1- в начале нашего номера телефона

Основываясь на том, что мы узнали, вы можете это понять?

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

Давайте пошагово…

Если вы хотите, чтобы номер телефона начинался с 1, мы добавляем ^1 в начало совпадения строки, верно? Теперь мы хотим добавить тире или пробел после 1. К счастью, мы уже знаем, как это сделать: [ -]?.

Объединяя 2, мы получаем: ^1[ -]?

Добавив это к нашему предыдущему регулярному выражению, мы получим:

^1[ -]?\d{3}[ -]?\d{3}[ -]?\d{4}$

Вы чувствуете, что здесь что-то не так? Вышеприведенное соответствие строки регулярного выражения ДОЛЖНО начинаться с 1, это необязательно. Нам нужно сделать 1[ -]? необязательным.

Как мы это делаем? Поскольку здесь мы говорим о нескольких элементах: 1 и [ -]?, нам нужно поместить все это в (...), создав группу. Затем добавьте ? после него, чтобы сделать всю группу необязательной!

Я знаю, что многое нужно принять! Вот как это выглядит:

^(1[ -]?)?\d{3}[ -]?\d{3}[ -]?\d{4}$

Давайте снова разберем его, но теперь с дополнительным шагом:

  1. ^(1[ -]?)?необязательно начните с 1, за которым необязательно следует пробел ИЛИ тире
  2. \d{3} ⇾ начните с 3 цифр
  3. [ -]?необязательно с последующим пробелом ИЛИ тире
  4. \d{3} ⇾ с последующими 3 цифрами
  5. [ -]?необязательно с последующим пробелом ИЛИ тире
  6. \d{4}$ ⇾ заканчивается на 4 цифры

🤯

Если вы все еще читаете, поздравляю, теперь вы знаете, как думать «регулярные выражения»!

Осталась еще одна нерешенная проблема: как сопоставить номер телефона, например: (202)515 5555. Я оставлю это для читателя (подсказка: используйте оператор канала: (...|...)).

Собираем все вместе, чтобы протестировать строку фактического номера телефона

Теперь давайте возьмем наше регулярное выражение и превратим его в регулярное выражение на JavaScript. Для этого просто добавьте /.../ вокруг него. Затем используйте метод под названием test:

const regex = /^(1[ -]?)?\d{3}[ -]?\d{3}[ -]?\d{4}$/;
const phoneNumber = '1202-515-5555';
// test returns 'true' if there's a match and 'false' if there is not
const match = regex.test(phoneNumber);

Если вы хотите правильно изучить регулярное выражение, вот ОТЛИЧНОЕ бесплатное руководство: RegexOne. Это буквально то, как я изучил Regex. Стоит пройти ВСЕ упражнения.

Если вам понравилась эта статья, загляните в мой блог Углубленный JavaScript для получения дополнительной информации. 🤓