Операции с регулярными выражениями

В данной главе неоднократно упоминались операции с регулярными выражениями, такие как поиск по образцу. Основными операциями этого типа являются операция поиска m//, операция замены s/// и операция транслитерации tr///.

Операция поиска

Операция поиска m/PATTERN/ осуществляет поиск образца PATTERN. Общая форма записи этой операции имеет вид:
m/PATTERN/cgimosx
Результатом операции является значение 1 («истина») или пустая строка («ложь»). По умолчанию поиск осуществляется в строке, содержащейся в специальной переменной $_, Можно назначить другую строку для поиска в ней заданного образца при помощи операций связывания =~ или !~:
$var =~ m/PATTERN/cgimosx
В результате последней операции поиск образца PATTERN будет осуществляться в строке, задаваемой переменной $var. Если в правой части операции связывания стоит операция поиска m//, то в левой части не обязательно должна находиться переменная, а может быть любое строковое выражение.
Операция !~ отличается от операции =~ тем, что возвращает противоположное логическое значение. Например, в результате поиска в строке "аaаbbbссс" образца /b+/:
$s = "aaabbbccc" =~ m/b+/;
$s = "aааbbbссс" !~ m/b+/;
в обоих случаях будет найден фрагмент bbb. Но в первом случае возвращаемое значение, сохраненное в переменной $s, будет равно 1 («истина»), а во втором случае — пустой строке («ложь»).
Образец PATTERN может содержать переменные, значения которых подставляются при каждом выполнении поиска по данному образцу.
Флаги cgimosx модифицируют выполнение операции поиска. Флаги imsx имеют тот же смысл, что и в рассмотренном выше случае конструкции расширенного регулярного выражения (?imsx-imsx):
Рассмотрим функции остальных флагов.
g — задает глобальный поиск образца в заданной строке. Это означает, что будут найдены все фрагменты текста, удовлетворяющие образцу, а не только первый из них, как имеет место быть по умолчанию. Возвращаемое значение зависит от контекста. Если в составе образца имеются подобразцы, заключенные в скобки (...), то в контексте массива для каждого заключенного в скобки подобразца возвращается список всех найденных фрагментов. Если в составе образца нет подобразцов, заключенных в скобки, то в контексте массива возвращается список всех найденных фрагментов, удовлетворяющих образцу. В скалярном контексте каждая операция m//g осуществляет поиск следующего фрагмента, удовлетворяющего образцу, возвращая значение 1 («истина»), если фрагмент найден, и пустую строку, если фрагмент не найден. Позиция строки, в которой завершился последний поиск образца при установленном флаге g, может быть получена при помощи встроенной функции pos( ). Обычно при неудачном поиске начальная позиция поиска восстанавливается в начало строки. Флаг с отменяет восстановление начальной позиции поиска при неудачном поиске образца.
с — используется совместно с флагом g. Отменяет восстановление начальной позиции поиска при неудачном поиске образца.
о — значения переменных, входящих в состав образца PATTERN, подставляются только один раз, а не при каждом поиске по данному образцу.
В качестве символов-ограничителей для выделения образца можно использовать любую пару символов, не являющихся цифрой, буквой или пробельным символом. Если в качестве ограничителя используется символ /, то литеру m в обозначении операции можно опустить и использовать упрощенную форму /PATTERN/ вместо m/PATTERN/.
Если в качестве ограничителя используется одинарная кавычка ', то подстановка значений переменных внутри образца не производится.
Если в качестве ограничителя используется символ ?: ?PATTERN?, то при применении операции поиска находится только одно соответствие.

Операция замены

Операция замены s/PATTERN/REPLACEMENT/ осуществляет поиск образца PATTERN и, в случае успеха, замену найденного фрагмента текстом REPLACEMENT. В общем виде операция замены может быть записана следующим образом:
s/PATTERN/REPLACEMENT/egimosx
Возвращаемым значением является число сделанных замен или пустая строка («ложь»), если замен не было. По умолчанию поиск и замена осуществляются в специальной переменной $_. Ее можно заменить другой строкой при помощи операций связывания =~ или !~:
$var =~ s/PATTERN/REPLACEMENT/egimosx
Флаг g задает глобальную замену всех фрагментов, удовлетворяющих образцу PATTERN, текстом REPLACEMENT.
Флаг е означает, что заменяющий текст REPLACEMENT следует рассматривать как Perl-выражение, которое следует предварительно вычислить. Например, в результате выполнения сценария
$str = "abaabbaaabbbaaaabbbb";
$result = $str =~ s/(a+b+)/length($1)/ge;
print "result = $result new str = $str\n";
будет выведено число сделанных замен $result и новое значение строки $str, в которой каждый найденный фрагмент, соответствующий образцу [а+b+], заменен числом, равным его длине:
result = 4 new str = 2468
Флаги imosx имеют тот же смысл, что для операции поиска m//.
Как и в операции замены, в качестве ограничителей для выделения образца можно использовать любую пару символов, не являющихся цифрой, буквой или пробельным символом. Можно использовать различные ограничители для выделения образца и замещающего текста, например s(pattern)<replacement>.

Операция транслитерации

Операция транслитерации преобразует каждый символ из списка поиска SEARCHLIST в соответствующий символ из списка замены REPLACEMENTLIST и возвращает число преобразованных символов. Общая форма записи операции транслитерации имеет вид:
tr/SEARCHLIST/REPLACEMENTLIST/cds
По умолчанию преобразования осуществляются в строке, задаваемой переменной $_. Как и в рассмотренных выше операциях поиска и замены, при помощи операций связывания =~ и !~ можно задать для преобразования строку, отличную от принятой по умолчанию:
$str =~ tr/SEARCHLIST/REPLACEMENTLIST/cds
Списки SEARCHLIST и REPLACEMENTLIST задаются перечислением символов, могут содержать диапазоны — два символа, соединенных знаком -, и иметь собственные символы-ограничители, например tr(a-j)/0-9/. Операция tr///имеет синонимичную форму, используемую в потоковом редакторе sed:
y/SEARCHLIST/REPLACEMENTLIST/cds
Флаги cds имеют следующий смысл:
Приведем примеры применения операции tr//.
Преобразование прописных букв в строчные:
$str =~ tr/A-Z/a-z/;
Подсчет числа символов в строке $str:
$count = $str =~ tr/\000//c;
Преобразование в единственный пробел любой последовательности символов с ASCII-кодами от 128 до 255:
$str =~ tr/\200-\377/ /cs;
Преобразование в сценарии русского текста в DOS-кодировке 866, содержащегося в файле 866.txt, в русский текст в Windows-кодировке 1251, и запись преобразованного текста в файл 1251.txt
open(IN866,"866.txt");
open(OUT1251,">125l.txt");
while ($line=<IN866>) {
  $line =~ tr/\200-\257\340-\361/\300-\377\250\270/;
  print OUT1251 $line; 
}
close(IN866);
close(OUT1251);

Операция заключения в кавычки qr//

Операция заключения в кавычки qr// по своему синтаксису похожа на другие операции заключения в кавычки, такие как q//, qq//, qx//, qw//. Она имеет следующую общую форму записи:
qr/STRING/imosx
Операция qr// рассматривается в данном разделе, так как имеет непосредственное отношение к регулярным выражениям. Регулярное выражение, содержащее переменные, метасимволы, метапоследовательности, расширенный синтаксис, перед использованием должно быть обработано компилятором. Операция qr// осуществляет предварительную компиляцию регулярного выражения STRING, преобразуя его в некоторое внутреннее представление с тем, чтобы сохранить скомпилированное регулярное выражение в переменной, которую затем можно использовать без повторной компиляции самостоятельно или в составе других регулярных выражений.
Преимущества применения операции qr// проявляются, например, в следующей ситуации. Допустим, что мы собираемся многократно использовать в качестве образца достаточно сложное регулярное выражение, скажем,
/^([^ ]*) *([^ ]*)/.
Его можно использовать непосредственно в операции сопоставления с образцом:
if ($line =~ /^([^ ]*) *([^ ]*)/) {...}
или сохранить в переменной $pattern = "^([^ ]*) *([^ ]*)" и обращаться к переменной:
if ($line =~ /$pattern/)  {...}
В обоих случаях регулярное выражение при каждом обращении обрабатывается компилятором, что при многократном использовании увеличивает время выполнения. Если сохранить образец при помощи операции qr//:
$pattn = qr/^([^ ]*) *([^ ]*)/
то переменная $pattn будет содержать откомпилированное регулярное выражение, которое можно неоднократно использовать без дополнительной компиляции.
Флаги imosx имеют тот же смысл, что и в операции замены m//.

Следующая страница Содержание главы


Реклама