Perl практика

         

Дизьюнкция.


a|b|c - означает, что данный образец соответствует только одному из указанных вариантов. Такая конструкция работает и для класса символов, как в образце /igor|mike/.



Фиксирование образцов.


Некоторые особые виды записи позволяют фиксировать образец относительно позиции в строке, в кот. ищется соответствие.

Фиксирующая деректива \b требует, чтобы совпадение с образцом b происходило только на границе слова.

/fred\b/; # соответствует слову fred, но не Frederik /\bmo/; # соответствует словам moe и mole, но не Elmo /\bFred\b/; # соответствует слову Fred, но не Frederik или alFred /\b\+\b/; # соответствует "x+y", но не "++" или " + "

\B требует, чтобы в указанной точке границы слова не было. Символ ^ обозначает начало строки. Символ $ фиксирует образец по концу строки.

Поддерживаются и другие фиксирующие точки.



Функции split и join.


$line = "gds::*::1001::20::Samolyuk German::/home/gds::/usr/local/bin/tcsh"; @fields = split(/:/, $line); # разбить $line, используя в качестве # разделителя двоеточие # @fields содержит ("gds","","*","","1001","","20","","Samolyuk German","", # "/home/gds","","/usr/local/bin/tcsh")

Второе поле : стало пустой строкой, если вы этого не хотите:

@fields = split(/:+/, $line);

Использование автоматической переменной:

$_ = "this is a some text"; @words = split(/ /); # @words = split(/ /, $_);

Соседние пробелы вызовут появление пустых строк. Лучше использовать образец / +/

или /\s+/. Или по умолчанию:

@words = split; # @words = split(/\s+/, $_);

Пример:



$line = "gds::*::1001::20::Samolyuk German::/home/gds::/usr/local/bin/tcsh"; ($name, $password, $uid, $gid, $gcos, $home, $shell, $a) = split(/:+/, $line); # $a - undef

Функция join берет список значений с склеивает их, ставя между элементами списка строку связку:

$string = join($glue, @list); $outline = join(":", @fields);



Игнорирование регистра.


Игнорирование регистра /образец/i.

print "any last request? "; if(<STDIN&gt =~ /^y/i) { ... }



Использование другого разделителя.


Для нахождения строки, которая содержит несколько символов (/), нужно перед каждым из них поставить обр. косую черту.

$path = <STDIN>; # прочитать путь if(path =~ /^\/usr\/etc/) { # начинается с /usr/etc... }

Можно заменить разделитель, если перед любым специальным символом поставить букву m.

/^\/usr\/etc/ m@^/usr/etc@ m#^/usr/etc#



Использование интерполяции переменных.


Перед тем как регулярное выражение расспатривается, в нем производится интерполяция переменных

$what = "bird"; $sentence = "Every good bird does fly."; if($sentence =~ /\b$what\b/) { print "The centence contains theword $what!\n"; }



Круглые скобки как способ запоминания.


При совпадении с образцом никаких изменений не происходит, просто совпавшая часть строки запоминается, и к ней можно впоследствии обращаться. Например, (a) продолжает соответствовать букве a, а ([a-z]) - любой строчной букве.

Чтобы вызвать часть строки, который программа запомнила, нужно поставить косую черту и целое число.

/mike(.)igor\1/

Соответствует строке, состоящей из слова mike, любого символа, слова igor и еще одного такого же символа. Единица обозначает первую заключенную в круглые скобки часть регулярного выражения. Если таких частей больше, чем одни, то вторая обозначается как \2 ...

/a(.)b(.)c\2\1/;

Запоминаемая часть может состоять не только из одного символа.

/a(.*)b\1c/;

- a, любое количество символов, b, ту же последовательность символов, и c.



Множители.


* - ни одного или более экземпляров стоящего непосредственно перед ней символа.

+ - один или более экземпляров стоящего непосредственно перед нем символа.

? - ни одного или один экземпляр стоящего непосредственно перед ним символа.

Например, регулярное выражение /fo+ba?r/ обозначает символ f, за которым следует один или более символов o, затем символ b, затем ни одного или один символ a

и символ r.

$_ = "mike xxxxxxxxxxxxx nick" s/x+/igor/;

В последнем примере все символы x будут заменемы на igor (описанные выше образцы характеризуются
&quot прожорливостью &quot). Простой способ избежать этого - применение общего множителя.

/x{5,10}/ - найти символ, стоящий перед скобками, повторяющийся от пяти до десяти раз.

/x{5,}/ - найти символ, стоящий перед скобками, повторяющийся от пяти раз.

/x{5}/ - найти символ, стоящий перед скобками, повторяющийся ровно пять раз.

/x{,5}/ - найти символ, стоящий перед скобками, пять раз или менее.

/a.{5}b/ - соответствует букве a, отделенной от буквы b любыми пятью символами.

Если в одном выражении используются два множителя, то правило &quot прожорливости&quot дополняется правилом "чем левее, тем прожорливее &quot. Например:

$_ = "a xxx c xxxxxxxx c xxx d"; /a.*c.*d/;

Первая комбинация &quot.*&quot соответствует всем символам до второй буквы c.

Можно заставить любой множитель перестать быть "прожорливым", поставив после него вопросительный знак:

$_ = "a xxx c xxxxxxxx c xxx d"; /a.*?c.*d/;

Теперь a.*?c соответствует манимальному числу символов между a и c, а не максимальному.



Образцы, обозначающие один символ.


Одиночный символ соответствует самому себе. Символ точка - любой одиночный символ, кроме символа новой строки (\n). Например, образцу /a./ соответствует любая двухбуквенная поседовательность, начинающаяся с a.

Класс символов сопоставления:

/[abcde] # строка, содержащая любую из первых пяти строчных букв /[aeiouAEIOU] # -//- из первых пяти гласных

Диапазоны символов:

[0123456789] [0-9] [0-9\-] [a-z0-9] [a-zA-Z0-9_]

Отрицание класса символов:

[^0-9] [^aeiouAEIOU] [^\^]

Предопределенные классы символов

Конструкция

Эквивалентный класс

Конструкция с отрицанием

Эквивалентный класс с отрицанием

\d (цифра)

[0-9]

\D (нецифровые символы)

[^0-9]

\w (обычный символ)

[a-zA-Z0-9_]

\W (специальный символ)

[^a-zA-Z0-9_]

\s (пробельный символ)

[ \r\t\n\f]

\S (непробельный символ)

[^ \r\t\n\f]

Пример:

[\da-fA-F] # одна шестнадцатеричная цифра



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


Простая форма операции замены: s/регулярное_выражение/новая_строка/

При всех возможных совпадениях:

$_ = "foot fool buffoon"; s/foo/bar/g; # $_ -> "bart barl bufbarn"

В заменяущей строке производится интерполяция переменных

$_ = "hello, world!"; $new = "goodbye"; s/hello/$new/;

Можно ипользовать сопоставление с образцом

$_ = "this is a test"; s/(\w+)//g;

При помощи операции =~ можно указать другой обьект для операции замены

$which = "this is a test"; $which =~ s/test/quiz/;



Основные направления использования регулярных выражений.


if(/abc/) { print $_; }

В примере с регулярным выражением abc сравнивается переменная $_. Этот фрагмент Perl программы рассметривает только одну строку. Для обработки всех строк:

while(<&gt) { if(/abc/) { print $_; } }

Пример:

while(<&gt) { if(/ab*c/) { print $_; } }

Ищется последовательность, содержащая символ a, ни одного или более символа b и символ c.

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

s/ab*c/def/;

Переменная ($_ в данном случае) сопоставляется с рег. выражением и с случае успеха заменяется строкой def.



Основные понятия.


Регулярное выражение представляет собой образец - шаблон - который сопоставляется со строкой. Сопоставление со строкой дает либо успешный результат, либо неудачный.



Приоритет.


Приоритет групповых регулярных выражений.

НаименованиеОбозначение

Примеры:

abc* # ab, abc, abcc, abccc ... (abc)* # "", ab, abc, abcabc, abcabcabc ... ^x|y # x в начале строки или y в любом месте ^(x|y) # x или y в начале строки a|bc|d # либо a, либо bc, либо d (a|b)(c|d) # ac, ad, bc, или bd (song|blue)bird # songbird или bluebird



Выбор другого обьекта для сопоставления.


Если строка, которую нужно сопоставить с образцом, не находится в переменной $_, то можно воспользоваться операцией =~. Пример:

$a = " hello world"; $a =~ /^he/; # истина $a =~ /(.)\1/; # истина (соответствует двум l) if($a =~ /(.)\1/) { #истина }

Слева от знака операции =~ может стоять любое выражение:

print "any last request? "; if( <STDIN&gt =~ /^[yY]/) { print "And just what might that request be? ";

<STDIN>; print "Sorry, I'm unable to do that.\n"; }









Круглые скобки ( ) (?: )
Множители ? + * {m, n} ?? +? {m, n}?
Последовательность и фиксация abc ^ $ \A \Z (?= ) (?! )
Дизьюнкция |