Сегодняшней темой будут регулярные выражения, также известные как регулярные выражения. Возможно, вы слышали об использовании регулярных выражений для «сопоставления строк» ​​и задавались вопросом, что это значит и как это работает. Моя цель здесь — предоставить достаточно информации, чтобы вы могли начать использовать их самостоятельно в соответствующих местах своего кода. С практикой правильно сформированное регулярное выражение может значительно сократить и упростить задачу проверки того, что строки символов соответствуют определенным критериям (например, введенным пользователем адресам электронной почты или журналам за определенную дату). Однако, если вы видели их в использовании, не зная, что они из себя представляют, они могут показаться безнадежно сложными.

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

Идея регулярных выражений состоит в том, чтобы кодировать определенные шаблоны, которые появляются в словах («слова» здесь действительно означают общие строки символов, которые также могут включать числа, символы и пробелы) с помощью символов, чтобы компьютер мог распознавать слова, которые принадлежат определенный набор, также известный как «язык». Примером языка, который можно распознать с помощью регулярных выражений, может быть набор всех строк длиной не менее одного символа, содержащих количество единиц, кратное трем (так что 1101, 101001, 0 и 1111110111 будут в язык, но 11 не будет). Мы говорим, что регулярное выражение «распознает» язык, если оно принимает каждую строку на этом языке и отвергает каждую строку, не принадлежащую этому языку. Вот пример регулярного выражения, распознающего описанный выше язык:

/^(0*10*10*1|0)+$/

Я говорю «один», а не «то» регулярное выражение, потому что может быть много примеров, которые распознают один и тот же язык. Давайте посмотрим, что делают эти символы. Первый и последний символы «/» обозначают, что внутри находится регулярное выражение (в разных языках программирования для этого используются разные разделители, но «/» встречается довольно часто). На один шаг внутрь мы видим «^» и «$». Эти символы обозначают начало и конец строки, которую нужно сопоставить. Это может показаться излишним, но в этом примере это не так, поскольку строка, содержащая шесть единиц, также будет содержать подстроки только с тремя единицами (и здесь мы хотим сопоставить только целую строку). Далее, давайте посмотрим на «+». «+» говорит о том, что выделение непосредственно перед ним появляется один или несколько раз (здесь «выделение» означает один символ или группу. О группах можно сказать больше, но пока достаточно сказать, что скобки разграничивают группу). В этом примере «+» гарантирует, что пустая строка не является совпадением, поскольку внутри группы должно быть хотя бы одно из того, что появляется. «*» следует в списке. Он очень похож на «+», с той лишь разницей, что он соответствует предшествующему символу 0 или более раз (т. е. первый «0» в выражении может встречаться любое количество раз, включая ноль раз). Наконец, «|» используется для обозначения того, что одна или другая из вещей, которые он разделяет, должны соответствовать регулярному выражению, но не оба. Теперь, когда вы знаете, что означают символы, попробуйте доказать себе, что регулярное выражение, приведенное выше, соответствует только непустым строкам, содержащим единицы, кратные трем.

Давайте посмотрим на другой пример:

/^(1-)?\([0-9]{3}\)-[0-9]{3}-[0-9]{4}$/

Это регулярное выражение соответствует номерам телефонов в форме 1-(***)-***-****, где 1 может быть опущен. Символ «?» похож на «*» и «+» в том, что он влияет только на символ или группу, непосредственно предшествующую ему, но он используется для обозначения того, что на этом месте находится либо 0, либо 1 вещь. Следовательно, перед номером телефона может или не может стоять «1-». Далее мы видим «\». Он действует как escape-символ, указывая на то, что следующий символ является специальным. Здесь он используется, чтобы указать, что регулярное выражение должно соответствовать фактическим круглым скобкам, а не использовать их для группировки того, что находится внутри них. Сравните с первым набором скобок: «(1-)?» будет соответствовать одному или нулю экземпляров «1-», тогда как «\(\)» будет соответствовать паре открывающих и закрывающих скобок. Далее мы видим это: [0–9]. Это комбинация двух символов: «[]» и «-» и цифр 0 и 9. Квадратные скобки используются для обозначения того, что регулярное выражение должно соответствовать только одному из символов, содержащихся между ними, а «-» используется как оператор диапазона, когда он появляется между двумя неэкранированными или специальными символами. Таким образом, [0–9] соответствует одной цифре в диапазоне 0–9. За квадратными скобками следует число в фигурных скобках. Это сокращение используется для обозначения того, что символ или группа, предшествующая ему, должны повторяться указанное количество раз. Собрав все это вместе, мы видим, что регулярное выражение должно соответствовать строкам, которые могут начинаться или не начинаться с «1-», за которыми следуют три цифры в скобках, дефис, еще три цифры, еще один дефис, а затем еще четыре цифры. (Можно еще больше сократить это, используя специальный символ «\d», который является сокращением для «[0–9]».)

То, что я представил сегодня, — это небольшой фрагмент того, что известно о регулярных выражениях. Я рекомендую regular-expressions.info для получения дополнительной информации по теме и regex101.com для тестирования регулярного выражения, которое вы хотите использовать в своем коде. Я надеюсь, что это немного прояснило тему регулярных выражений для новичка. Удачного кодирования.