Ранее в этой лекции уже упоминался модификатор /i, устанавливающий поиск с игнорированием разницы между заглавными и строчными буквами. Перечислим модификаторы для операции сопоставления:
[x]. /g - искать в тексте все соответствия образцу (Global);
[x]. /i - искать соответствие образцу без учета регистра букв (case-Insensitive);
[x]. /s - рассматривать текст как одну строку (Single-line);
[x]. /m - рассматривать текст как многострочный (Multi-line) с учетом n ;
[x]. /o - один раз откомпилировать регулярное выражение (Once);
[x]. /x - использовать расширенный синтаксис регулярных выражений (eXtended).
Из всех модификаторов, пожалуй, самый интересный - последний, который позволяет записывать регулярные выражения в структурированном и понятном для человека виде и даже сопровождать комментариями! Так, например, можно более понятно и красиво переписать регулярное выражение, приведенное в начале лекции:
m/ # начало регулярного выражения <A # начало тега: <A [^>]+? # далее могут быть любые символы, кроме > HREF # определение гиперссылки s*=s* # знак =, возможно окруженный пробелами ["']? # может быть открывающая кавычка или апостроф ( # начало захвата значения [^'" >]+? # адрес ссылки: все, кроме ',",пробела и > ) # конец захвата значения ['"]? # может быть закрывающая кавычка или апостроф s* # за которым могут быть пробелы > # конец тега /igx; # конец регулярного выражения # соответствует, например: <a id='ru' href="index.html">
Записанное в таком виде, регулярное выражение становится доступным для понимания, анализа и модификации. А поскольку регулярные выражения компилируются, то пробельные символы и комментарии не влияют на быстродействие программы.
Кроме поиска, регулярные выражения часто применяются для замены найденных совпадений на новые значения. Для этого существует операция замены (substitution), которая пытается найти в строковой переменной соответствие образцу, а если находит, то заменяет найденную подстроку на указанное значение. Операция замены выглядит так:
$variable =~ s/образец/замена/; # в переменной $variable отыскивается строка 'образец', # и если найдена, то она заменяется на 'замена'
Все, что говорилось до этого про операцию сопоставления, применимо для левой части операции замены, в которой указывается образец поиска. Левая и правая части операции замены интерполируются, поэтому там могут использоваться escape-последовательности и переменные.
$pattern = 'шило'; # образец $replacement = 'мыло'; # замена $text =~ s/$pattern/$replacement/; # поменять 'шило' на 'мыло'
В правой части операции замены могут использоваться обратные ссылки на найденные значения. Так, например, можно поменять местами два крайних слова в тройке слов, разделенных пробельными символами:
$text = 'мать любит дочь'; $text =~ s/(S+)s+(S+)s+(S+)/3 2 1/; # в $text будет 'дочь любит мать'
Для операции замены s/// можно применять все модификаторы, упомянутые для операции сопоставления m//. Например, модификатор /g указывает, что должны быть заменены все найденные в тексте соответствия. Например:
$our_computers =~ s/Windows/Linux/g;
У операции замены есть дополнительный модификатор /e (expression evaluation), при включении которого заменяющая часть вычисляется как выражение. При этом в заменяющей части можно использовать ссылки на захваченные при помощи круглых скобок соответствия. Это можно применять для более "интеллектуальной" замены найденных соответствий. Так, например, можно перевести температуру из шкалы Цельсия в шкалу Фаренгейта:
$text = 'Бумага воспламеняется при 233C.'; $text =~ s/(d+.?d*)Cb/int($1*1.8+32).'F'/e; # в $text будет: 'Бумага воспламеняется при 451F.'
Регулярные выражения применяются во многих конструкциях. В функции split() первым параметром может использоваться регулярное выражение, которое будет служить для поиска разделителей при разделении строки на части. Так, например, можно разбить строку на подстроки по любому из пробельных символов:
@substrings = split /s+/, $text; # разбить на части
Регулярные выражения часто применяются в функциях, работающих с массивами для фильтрации нужных элементов. Например, функция grep() возвратит список элементов массива, соответствующих указанному образцу:
@result = grep /$pattern/, @source; # отобрать элементы
С помощью функции map можно применить операцию замены в соответствии с регулярным выражением ко всем элементам массива, например:
@hrefs = ('http://regex.info', 'http://regexp.ru'); map s{http://}{}, @hrefs; # убрать 'http://' из ссылок
Регулярные выражения дают программисту новый взгляд на текстовые данные: вместо отдельных символов и простых подстрок он начинает мыслить обобщенными шаблонами, что помогает ему находить более простые и эффективные решения. В таблице 8.1 для справки приведены основные обозначения, применяемые для записи регулярных выражений в Perl. Дополнительные сведения о регулярных выражениях можно почерпнуть из стандартной документации по Perl и перевода уникальной книги Джеффри Фридла "Регулярные выражения".
Таблица 8.1. Основные обозначения для записи регулярных выраженийОбозначениеОписаниеПримеры//ограничители регулярного выражения по умолчанию/$pattern/отмена специального значения следующего символаm{C:\windows}()группировка шаблонов или сохранение значения/(www)+/|выбор из нескольких альтернатив/кошелек|жизнь/[]класс символов: любой символ из перечисленных/[0-9a-fA-F]/[^]инвертированный класс символов: любой символ, кроме перечисленных/[^0-9]/ Метасимволы .любой символ, кроме n (соответствует любому символу, включая n с модификатором /s)/(.+)/dдесятичная цифраm{Время=d+ сек}Dне десятичная цифра/(D*)d+/wалфавитно-цифровой знак/s+w+s+/Wне алфавитно-цифровой знак/WWW/sпробельный символs/s+/ /Sлюбой символ, кроме пробельного/S+/ Утверждения ^начало строки (соответствует началу каждой строки с модификатором /m)/^w+/$конец строки (соответствует концу каждой строки с модификатором /m)/d+$/bграница слова (между w и W или W и w)/stopb/Bлюбая позиция, кроме границы слова/stopB/Aтолько начало строки, даже с модификатором /m/A[#]/zтолько конец строки, даже с модификатором /m/w+z/Zтолько конец строки или перед n в конце строки, даже с модификатором /m/w+Z/Gпозиция в строке, равная значению функции pos() Escape-последовательности t n r f a bуправляющие символы: b в классе символов выступает как символ Backspace (0x08), вне его - как граница слова/[abfrnt]/ x c Nкоды символов/ 33x1FcZ/ /x{263a}/l L u U Q Eпреобразующие последовательности/Q$patternE/ Квантификаторы * *?любое число повторений, включая 0 (максимальный и минимальный квантификаторы)/s*/ /S*?/+ +?одно и более повторений (максимальный и минимальный квантификаторы)/d+/ /D+?/? ??ноль или одно повторение (максимальный и минимальный квантификаторы)/.?/ /[.a-z]??/{n} {n}?ровно n повторений (максимальный и минимальный квантификаторы)/w{8}/ /w{5}?/{n,} {n,}?n и более повторений (максимальный и минимальный квантификаторы)/d{2,}/ /d{5,}?/{n,m} {n,m}?от n до m повторений включительно (максимальный и минимальный квантификаторы)/[A-Z]{1,12}/ /[a-z]{0,3}?/