Первый сайт на Perl

Брат набросился на свою сестру и жестко трахнул


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

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

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

m/PATTERN/cgimosx

Операция поиска HI/PATTERN/ осуществляет поиск образца PATTERN. Результатом операции является значение 1 (ИСТИНА) или пустая строка"

(ЛОЖЬ). По умолчанию поиск осуществляется в строке, содержащейся в специальной переменной $_. Можно назначить другую строку для поиска в ней заданного образца при помощи операций связывания =~ или ! ~:

$var =~ m/PATTERN/cgimosx

В результате последней операции поиск образца PATTERN будет осуществляться в строке, задаваемой переменной $var. Если в правой части операции связывания стоит операция поиска т//, то в левой части может находиться не обязательно переменная, а любое строковое выражение.

Операция ! ~ отличается от операции =~ тем, что возвращает противоположное логическое значение. Например, в результате поиска в строке "aaabbbccc" образца /b+/Г

$s="aaabbbccc" =~ m/b+/; $s="aaabbbccc" !~ m/b+/;,

в обоих случаях будет найден фрагмент ььь. Но в первом случае возвращаемое значение, сохраненное в переменной $s, будет равно 1 (ИСТИНА), а во втором случае — пустой строке " (ЛОЖЬ).

Образец PATTERN может содержать переменные, значения которых подставляются при каждом выполнении поиска по данному образцу.

Флаги cgimosx модифицируют выполнение операции поиска. Флаги imsx имеют тот же смысл, что и в рассмотренном выше случае конструкции расширенного регулярного выражения (?imsx-imsx) .

  • i — поиск без учета регистра;
  • m — трактуется как мульти-строка, состоящая из нескольких строк, разделенных символом новой;
  • s — строка трактуется как одна строка, в этом случае метасимволу "." со-, ответствует любой одиночный символ, включая символ новой строки;
  • х — разрешается использовать в образцах пробелы и комментарии.
  • стальные флаги выполняют следующие функции.
  • g — Задает глобальный поиск образца в заданной строке. Это означает, что будут найдены все фрагменты текста, удовлетворяющие образцу, а не только первый из них, как имеет место по умолчанию. Возвращаемое значение зависит от контекста. Если в составе образца имеются подоб-разцы, заключенные в скобки (), то в контексте массива для каждого заключенного в скобки подобразца возвращается список всех найденных фрагментов. Если в составе образца нет подобразцов, заключенных в скобки, то в контексте массива возвращается список всех найденных фрагментов, удовлетворяющих образцу. В скалярном контексте каждая операция m//g осуществляет поиск следующего фрагмента, удовлетворяющего образцу, возвращая значение 1 (ИСТИНА), если он найден, и пустую строку ", если не найден. Позиция строки, в которой завершился последний поиск образца при установленном флаге g, может быть получена при помощи встроенной функции роз о (см. ниже). Обычно при неудачном поиске начальная позиция поиска восстанавливается в начало строки. Флаг с отменяет восстановление начальной позиции поиска при неудачном поиске образца.

Рассмотрим следующий скрипт.

$str="abaabbaaabbbaaaabbbb";

tt контекст массива, нет подобразцов в скобках

@result=$str =~m/a+b+/g;

print "контекст массива, нет конструкций в скобках:\n";

print "\@result=@result\n";

# контекст массива, есть конструкции в скобках, задающие обратные ссылки

@result=$Str =~m/(a+)(b+)/g;

print "контекст массива, есть конструкции в скобках:\n";

print "\@result=@result\n";

# скалярный контекст

print "скалярный контекст:\n";

while ($result=$str =~m/(a+)(b+)/g) {

print "result=$result, current match is $&, position=",pos($str),"\n"; }

Результатом его выполнения будет вывод:

контекст массива, нет конструкций в скобках:

@result=ab aabb aaabbb aaaabbbb

контекст массива, есть конструкции в скобках:

@result=a b aa bb ааа bbb aaaa bbbb

скалярный контекст:

result=l, current match is ab, position=2

result=l, current match is aabb, position=6

result=l, current match is 'aaabbb, position=12

result=l, current match is aaaabbbb, position=20

HI с — Используется совместно с флагом g. Отменяет восстановление начальной позиции поиска при неудачном поиске образца.

Рассмотрим скрипт

$str="abaabbaaabbbaaaabbbb";

while ($result=$str =~m/(a+)(b+)/g) {

print "result=$result, current match is $&, position=",pos($str),"\n";

} • print "last position=", pos($str), "\n";

Здесь поиск образца /а+ь+/ в строке $str осуществляется в цикле до первой неудачи. При последнем (неудачном) поиске начальная позиция поиска по умолчанию устанавливается в начало строки, в этом случае вывод имеет вид:

result=l, current match is ab, position=2 result=l, current match is aabb, position=6 result=l, current match is aaabbb, position=12 result=l, current match is aaaabbbb, position=20 last position=

Если глобальный поиск осуществлять при установленном флаге с:

while ($result=$str =~m/ (a+) (b+)/gc) {

то при последнем неудачном поиске начальная позиция поиска не переустанавливается. Вывод имеет вид:

result=l, current match is ab r position=2 result=l, current match is aabb, position=6 result=l, current match is aaabbb, position=12 result=l, current match is aaaabbbb, position=20 last position=20

При задании образца для глобального поиска m//g можно использовать ме-тапоследовательность \с, представляющую точку, в которой закончился последний поиск m//g. Например, в результате выполнения скрипта .

^^х

$str="l) abc 2) aabbcc 3) aaabbbccc 4) aaaabbbbcccc";

$str=~m/3\)\s+/g; \

! $str=~m/\Ga+/; ,'

сначала по образцу будет найден фрагмент "3)", а затем фрагмент, удовлетворяющий образцу /а+/ и расположенный сразу за точкой, в которой завершился последний поиск. Этим фрагментом является "ааа".

По— Значения переменных, входящих в состав образца PATTERN, подставляются только один раз, а не при каждом поиске по данному образцу. Рассмотрим, например, следующий скрипт:

@pattnlist=("a+", "Ы-", "с+", "d+") ; foreach $pattn (@pattnlist) (

$line = <STDIN>; $line =~ m/$pattn/o;

print "pattn=$pattn \$&= $&\n"; }

Массив gpattniist содержит список образцов "a+", "b+", "с+" и "d+". В цикле по элементам этого списка в переменную $iine считывается очередная строка из стандартного ввода. В ней осуществляется поиск по образцу, совпадающему с текущим элементом списка. Поскольку использован флаг о, подстановка значений в образце /$pattn/ будет осуществлена один раз за время жизни данной Peri-программы, т. е. в качестве образца на каждом шаге цикла будет использовано выражение "а+". Если операцию поиска осуществлять без флага о:

$line =~ m/$pattn/,

то в качестве образца будут последовательно использованы все элементы списка "а+", н b+", "с+" и "d+".

В качестве символов-ограничителей для выделения образца можно использовать любую пару символов, не являющихся цифрой, буквой или пробельным символом. Если в качестве ограничителя используется символ "/", то литеру m в обозначении операции можно опустить и использовать упрощенную форму /PATTERN/ BMeCTO m/PATTERN/.

Если в качестве ограничителя используется одинарная кавычка ', то подстановка значений переменных внутри образца не производится.

Если в качестве ограничителя используется символ "?": ?PATTERN?, то при применении операции поиска находится только одно соответствие. Например, в результате выполнения скрипта

$str="abaabbaaabbbaaaabbbb";

while ($result = $str =~ m?a+b+?g) (

print "result=$result, current match is $&, position=", pos($str),"\n";

}

будет найдено только первое соответствие образцу:

result=l, current match is ab, position=2

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

s/PATTERN/REPLACEMENT/egimosx

Операция замены S/PATTERN/REPLACEMENT/ осуществляет поиск образца PATTERN и, в случае успеха, замену найденного фрагмента текстом REPLACEMENT. Возвращаемым значением является число сделанных замен или пустая строка (ЛОЖЬ), если замен не былоТПо умолчанию поиск и замена осуществляются в специальной переменной $_. Ее можно заменить другой строкой при помощи операций связывания =~ или ! ~:

$var =~ s/PATTERN/REPLACEMENT/egimosx

Флаг $ задает глобальную замену всех фрагментов, удовлетворяющих образцу PATTERN,TeKCTOM REPLACEMENT.

Флаг е означает, что заменяющий текст REPLACEMENT следует рассматривать как Peri-выражение, которое надо предварительно вычислить. Например, в результате выполнения скрипта

$str="abaabbaaabbbaaaabbbb"; $result=$str =~s[ (a+b+)]<length($l)>ge; print "result=$result new str=$str\n";

будет выведено число сделанных замен $ result и новое значение строки $str, в которой каждый найденный фрагмент, соответствующий образцу [а+b+], заменен числом, равным его длине:

result=4 new str=2468

Флаги imosx имеют тот же смысл, что для операции поиска m//.

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

s(pattern)<replacement>.

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

tr/SEARCHLIST/REPLACEMENTLIST/cds

Преобразует каждый символ из списка поиска SEARCHLIST в соответствующий символ из списка замены REPLACEMENTLIST и возвращает число преобразованных символов. По умолчанию преобразования осуществляются в строке, задаваемой переменной $_. Как и в рассмотренных выше операциях поиска и замены, при помощи операций связывания =~ и ! ~ можно задать для преобразования строку, отличную от принятой по умолчанию

$str =~ tr/SEARCHLIST/REPLACEMENTLIST/cds

Списки SEARCHLIST и REPLACEMENTLIST задаются перечислением символов, могут содержать диапазоны — два символа, соединенных знаком "-", и иметь собственные символы-ограничители, например, tr(a-j) /0-9/. Операция tr/// имеет синонимичную форму, используемую в потоковом редакторе sed:

y/SEARCHLIST/REPLACEMENTLIST/cds

Флаги cds имеют следующий смысл.

  • с — вместо списка поиска SEARCHLIST использовать его дополнение до основного множества символов (обычно расширенное множество ASCII).
  • d — удалить все символы, входящие в список поиска SEARCHLIST, для которых нет соответствия в списке замены REPLACEMENTLIST. Если флаг d не установлен и список замены REPLACEMENTLIST короче, чем список поиска SEARCHLIST, то вместо недостающих символов в списке замены используется последний символ этого списка. Если список замены пуст, то символы из списка поиска SEARCHLIST преобразуются сами в себя, что удобно использовать для подсчета числа символов в некотором классе. П s — все последовательности символов, которые были преобразованы в один и тот же символ, заменяются одним экземпляром этого символа.

$str =~ tr/A-Z/a-z/; # преобразование прописных букв в строчные $count=$str=~tr/\000//c; # подсчет числа символов в строке $str $str =~ tr/\200-\377/ /cs; # любая последовательность символов

с ASCII-кодами от 128 до 255 преобразуется

в единственный пробел

Следующий скрипт преобразует русский текст в DOS-кодировке 866, содержащийся в файле "866.txt", в русский текст в Windows-кодировке 1251, и записывает преобразованный текст в файл "1251. txt".

open(IN866, "866.txt"); open(OUT1251,">125I.txt"); while ($line=<IN866>) { .

$line=~tr/\200-\257\340-\361/\300-\377\250\270/; print OUT1251 $line;

>

close(IN866); close(OUT1251);

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

qr/STRING/imosx

Операция qr// по своему синтаксису похожа^наГдругие операции заключения в кавычки, такие как q//, qq//, qx//, qw//. Она обсуждается в данном разделе, так как имеет непосредственное отношение к регулярным выражениям. Регулярное выражение, содержащее переменные, метасимволы, мета-последовательности, расширенный синтаксис, перед использованием должно быть обработано компилятором. Операция qr// осуществляет предварительную компиляцию регулярного выражения STRING, преобразуя его в некоторое внутреннее представление, с тем, чтобы сохранить скомпилированное регулярное выражение в переменной, которую затем можно использовать без повторной компиляции самостоятельно или в составе других регулярных выражений.

Преимущества от применения операции qr// проявляются, например, в следующей ситуации. Допустим, что мы собираемся многократно использовать в качестве образца достаточно сложное регулярное выражение, например, / ^ ([ ^ ]*) *([ ^ ]*)/. Его можно использовать непосредственно в операции сопоставления с образцом

if ($line =~ / ^ (Г ]*) *([ ^ ]*)/) {...},

или сохранить в переменной $pattern= ll/^ ([ ^ ]*) *([ ^ ]*) и обращаться к переменной:

if ($line =~ /$pattern/) (...},

В обоих случаях регулярное выражение при каждом обращении обрабатывается компилятором, что при многократном использовании увеличивает время выполнения. Если сохранить образец при помощи операции qr//:

$pattn = qr/~(r ]*) *<Г ]*)/,

то переменная $pattn будет содержать откомпилированное регулярное выражение, которое можно неоднократно использовать без дополнительной компиляции.

Флаги imosx имеют тот же смысл, что и в операции замены т//. Например, в следующем тексте операция qr// применяется с флагами ох:

$s="aA!Bb2cC3Dd45Ee";

@pattns=("\\d+ # последовательность цифр",

"[A-Z]+ t последовательность прописных букв", "[a-z]+ # последовательность строчных букв"); foreach $pattn Opattns) { my $pattern=qr/$pattn/ox; while ($s=~/$pattern/g) { $p=$p.$&; . } } print "s=$s p=$p\n";

В данном примере определен массив @pattns, состоящий из регулярных выражений. В цикле по элементам массива проверяется наличие в заданной строке $з фрагмента, соответствующего текущему образцу. Найденный фрагмент добавляется в конец строки $р. Флаг х в операции qr// позволяет использовать образцы в том виде, в каком они хранятся в массиве — с пробелами и комментариями. Если в операции qr// флаг о не установлен, то в результате выполнения скрипта строка $р будет состоять из символов строки $s, расположенных в следующем порядке: сначала все цифры, затем все прописные буквы, затем все строчные буквы. Если, как в данном ^тексте, флаг о установлен, то в операции $pattern=qr/$pattn/ox подстановка переменной $pattn произойдет только один раз, и строка $s будет три раза проверяться на наличие фрагмента, удовлетворяющего первому образцу $pattns[i]. В результате строка $р будет состоять только из цифр, входящих в строку $s, повторенных три раза.

Назад Начало Вперед