Регулярные выражения: =~ и совпадения

Регулярное выражение — это шаблон, по которому можно искать кусочки текста. Например, шаблон, который означает «здесь должна быть цифра» или «здесь должно быть слово из букв». Регулярки используют для проверки email-адресов, поиска номеров телефонов, извлечения дат из текста и вообще везде, где нужно найти что-то «по образцу», а не по точному совпадению.

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

Оператор =~

Этот оператор называют оператором привязки (binding operator). Он берёт переменную слева и «привязывает» её к операции регулярного выражения справа. Самая частая операция — проверка совпадения, которая записывается через m/шаблон/ (буква m означает match, «совпадение»).

my $text = "Привет, мир!";

if ($text =~ m/мир/) {
    print "Слово 'мир' найдено!\n";
}

Вывод:

Слово 'мир' найдено!

Разберём построчно. В первой строке создаём переменную $text со строкой. Дальше в условии if пишем $text =~ m/мир/ — это означает «проверь, встречается ли в $text подстрока, которая совпадает с шаблоном мир». Если совпадение нашлось, вся конструкция =~ m/.../ возвращает истину, и мы попадаем внутрь if.

Кстати, букву m перед шаблоном можно опускать, если в качестве разделителя используются слэши — тогда просто пишут $text =~ /мир/. Это самый распространённый способ записи, его вы будете видеть в реальном коде чаще всего.

Метасимволы: не только буквы

Шаблон — это не просто точный текст для поиска. В регулярках есть специальные символы (метасимволы), которые означают что-то более общее. Например, точка . означает «любой символ», а \d означает «любая цифра».

my @lines = ("Заказ №102", "Заказ №58", "Ошибка ввода");

foreach my $line (@lines) {
    if ($line =~ /\d+/) {
        print "$line — есть номер\n";
    } else {
        print "$line — номера нет\n";
    }
}

Вывод:

Заказ №102 — есть номер
Заказ №58 — есть номер
Ошибка ввода — номера нет

Здесь шаблон \d+ означает «одна или несколько цифр подряд». Символ \d — это «любая цифра от 0 до 9», а плюс + — это квантификатор, который говорит «повтори предыдущий элемент один или больше раз». Так мы за один шаблон проверяем сразу целую последовательность цифр, а не одну конкретную.

Есть и другие полезные метасимволы: \w означает «символ слова» (буква, цифра или подчёркивание), \s — «пробельный символ» (пробел, таб, перенос строки), а звёздочка * — это «ноль или больше повторений» (в отличие от плюса, который требует хотя бы одного).

Извлечение самого совпадения

Проверка «есть или нет» — это только половина возможностей. Часто нужно не просто узнать, что совпадение есть, а получить сам найденный текст. Для этого оператор совпадения можно вызвать в «списковом контексте» — присвоить результат массиву.

my $phrase = "Урок начинается в 09:30 утра";

my ($time) = $phrase =~ /(\d{2}:\d{2})/;

print "Время урока: $time\n";

Вывод:

Время урока: 09:30

Круглые скобки (\d{2}:\d{2}) здесь играют двойную роль: они и часть шаблона (две цифры, двоеточие, ещё две цифры), и одновременно группа захвата — то, что попадёт в переменную. Запись {2} означает «ровно два повторения». Мы подробнее разберём группы захвата в следующем уроке — сейчас достаточно увидеть, что регулярка умеет не только искать, но и «вытаскивать» найденный кусочек текста.

Частые ошибки

Первая ошибка новичков — забыть, что символы вроде точки, звёздочки или скобок имеют особое значение. Если нужно найти literal-точку (например, в имени файла report.txt), её нужно экранировать обратным слэшем: \.. Иначе точка в шаблоне будет означать «любой символ», и шаблон случайно совпадёт с чем-то неожиданным, например с reportXtxt.

Вторая ошибка — путать =~ с обычным присваиванием =. Это разные операторы: одна тильда полностью меняет смысл строки. $text = /мир/ без тильды просто не будет делать то, что вы ожидаете.

Третья ошибка — забывать, что оператор совпадения по умолчанию ищет только первое вхождение. Если в строке несколько цифр подряд в разных местах, а нужны все — понадобится флаг g, о котором будет отдельный урок.

Итоги

Оператор =~ — это «мостик» между переменной и регулярным выражением в Perl. Конструкция $var =~ /шаблон/ проверяет совпадение и возвращает истину или ложь, а если обернуть результат в скобки для списка — можно получить и сам найденный текст через группы захвата. Метасимволы вроде \d, \w, \s вместе с квантификаторами +, *, {N} позволяют описывать не точный текст, а общую форму того, что мы ищем.

Проверьте себя
1. Какой оператор в Perl используется для привязки переменной к операции регулярного выражения?
A=~
B==
C=>
D->
2. Что означает метасимвол \d в регулярном выражении Perl?
AЛюбую букву
BЛюбую цифру
CЛюбой пробельный символ
DКонец строки