Хорошо, я смог понять «регулярное выражение»!
Что-то, что мне действительно было трудно понять, это регулярные выражения. Но недавно мои попытки узнать больше об этом «мистическом» материале окупились!
Вот скромная попытка объяснить, как я это понял.
Возьмите следующий литерал регулярного выражения JS:
/\(?[\d]{3}\)?[\s-]?[\d]{3}[\s-]?[\d]{4}/g
Он соответствует следующим форматам номеров телефонов:
(ххх)-ххх-хххх
ххххххххх
ххх-ххх-хххх
(ххх) ххх-хххх
Но как?!
Хорошо, давайте приступим!
Литералы JS Regex записываются внутри //.
ok
«g» после // является глобальным флагом, который означает, что мне нужно привести все совпадения в строке (т. е. до конца строки), а не только первое.
Достигнуто регулярное выражение -›//g
Теперь мы знаем, что формат номера телефона, на который мы ориентируемся, имеет базовую структуру: 3 цифры, 3 цифры, 4 цифры.
Как группа, цифры в регулярном выражении представлены через классы символов, которые записываются внутри []
Таким образом, полный диапазон цифр составляет [0–9]
Алфавит строчных букв [a-z]
Столица [А-Я]
Важно отметить, что если мы напишем [a-d], будут совпадать только буквы a,b,c,d.
Эти диапазоны настолько распространены, что у нас есть сокращение для достижения этого.
Таким образом, для 0–9 у нас есть \d, т.е. [0–9] станет [\d]
Количество символов представлено в {}, и это точные числа.
Что это значит?
a{3} будет соответствовать aaa , но не a или aa
Итак, возвращаясь к нашим 3 цифрам 3 цифрам 4 цифрам, мы получаем
[\d]{3}[\d]{3}[\d]{4}
- > /[\d]{3}[\d]{3}[\d]{4}/g
Теперь между 3 цифрами мы должны учитывать пробелы и дефисы, которых может и не быть.
Давайте учтем их!
Пробел на самом деле является собственным классом символов, представленным как \s, т.е. [\s]
Класс символов работает так, что он будет соответствовать чему угодно в пределах [].
Таким образом, мы можем учесть дефис, просто поставив «-» внутри []
, т. е. [\s-]
- > /[\d]{3}[\s-][\d]{3}[\s-][\d]{4}/g
Когда мы обсуждали {} , мы сказали, что он требует точного совпадения чисел.
Но он также принимает диапазоны. Что это значит?
{3} представляет ровно три, а {3,5} представляет от 3 до 5, а {3,} представляет 3 и все, что больше 3.
Таким образом, {0,1} будет означать либо 0, либо 1, т.е. необязательно.
Но секундочку! у нас есть сокращение для представления {0,1}, то есть ‘?’.
Так сказать, необязательный пробел [\s]? ; и в том же духе сказать необязательный пробел или дефис [\s-]?.
Хорошо, тогда к чему это нас приведет?
- > /[\d]{3}[\s-]?[\d]{3}[\s-]?[\d]{4}/g
Теперь для первых 3 цифр, то есть для кода города, мы также должны учитывать «необязательные» круглые скобки.
Давайте поработаем над этим:
На самом деле () — это специальный символ в регулярном выражении, представляющий то, что называется «группой захвата». это не то, что символ специального значения, а просто символ, пожалуйста, не находите в нем никаких скрытых смыслов!
Мы достигаем этого, добавляя префикс обратной косой черты «\».
Таким образом, мы избегаем круглых скобок, представляя их как \( и \).
- >/\([\d]{3}\)[\s-]?[\d]{3}[\s-]?[\d]{4}/g
Но мы знаем, что эта скобка необязательна, т.е. может быть в одних числах, которые мы получаем, и не может быть в других. Так что нам нужно учитывать и это, и мы делаем это, добавляя к нашей старой сделке суффикс «?»!
\(? и \)?
И вуаля! мы достигли желаемого литерала регулярного выражения!
> /\(?[\d]{3}\)?[\s-]?[\d]{3}[\s-]?[\d]{4}/g
PS: если вам нужно сопоставить только один номер, то есть вы не имеете дело с несколькими телефонными номерами в своей строке, вам не нужно добавлять глобальный флаг «g».
(Спасибо Джо Маддалоне на egghead.io, regex101.com и dassur.ma)