Регулярные выражения: =~ и совпадения
Регулярное выражение — это шаблон, по которому можно искать кусочки текста. Например, шаблон, который означает «здесь должна быть цифра» или «здесь должно быть слово из букв». Регулярки используют для проверки 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} позволяют описывать не точный текст, а общую форму того, что мы ищем.