Чаще всего регулярные выражения в Перл используются в операторах
поиска и замены таких как s// m/ операторах связки =~ или != и т. д.
Как правило все эти операторы имеют схожие опции такие как:
* i - не различать строчные и заглавные буквы;
* m - считать строку многострочной;
* s - однострочная строка;
* x - расширенный синтаксис ( использование пробелов и
комментариев).
Обычно все эти опции обозначают как '/x'. Их можно использовать даже
внутри шаблонов использую новую конструкцию (?...).
В шаблонах используются следующие метасимволы (символы обозначающие
группы других символов):
* - считать следующий метасимвол как обычный символ;
* ^ - начало строки;
* . - один произвольный символ. Кроме 'n' - конец строки;
* $ - конец строки;
* | - альтернатива (или);
* () - группировка;
* [ ] - класс символов.
Метасимволы имеют модификаторы (пишутся после метасимвола):
* * - повторяется 0 или большее число раз;
* + - повторяется 1 или большее число раз;
* ? - 1 или 0 раз;
* {n} - точно n раз;
* {n,} - по меньшей мере раз;
* {n,m} - не менше n, но и не больше m.
Во все других случаях фигурные скобки считаются обычными (регулярными)
символами. Таким образом '*' эквивалентна {0,} , '+' - {1,} и '?' -
{0,1}. n и m не могут быть больше 65536.
По умолчанию действие метасимволов <<жадно>> (greedy). Совпадение
распространяется столько раз сколько возможно не учитывая результат
действия следуюющих метасимволов. Если вы хотите "уменьшить их
аппетит" то используйте символ '?'. Это не изменяет значение
метасимволов просто уменьшает распространение. Таким образом:
* *? - станет 0 и более;
* +? - 1 и более;
* ?? - 0 или 1 раз;
* {n}? - точно n раз;
* {n,}? - не меньше n раз;
* {n,m}? - больше или равно n и меньше m раз.
Шаблоны работают так же, как и двойные кавычки поэтому в них можно
использовать `` - символы (бакслэш-символы):
* t - символ табуляции;
* n - новая строка;
* r - перевод каретки;
* а - перевол формата;
* v - вертикальная табуляция;
* a - звонок;
* e - escape;
* 33 - восьмеричная запись символа;
* x1A - шестнадцатеричная;
* c[ - control символ;
* l - нижний регистр следующего символа;
* u - верхний регистр следующего символа;
* L - все символы в нижнем регистре до E;
* U - в верхнем регистре до E;
* E - ограничитель смены регистра;
* Q - отмена действия как метасимвола.
Дополнительно в Perl добавлены следующие метасимволы:
* w - алфавитно-цифровой или '_' символ;
* W - не алфавитно-цифровой или '_' символ;
* s - один пробел;
* S - один не пробел;
* d - одна цифра;
* D - одна не цифра.
Обратите внимание что все это <<один>> символ. Для обозначения
последовательности применяйте модификаторы, например:
* w+ - слово;
* d+ - целое число;
* [+-]?d+ - целое со знаком;
* [+-]?d+.?d* - число с точкой.
Кроме того существуют мнимые метасимволы. Обозначающие не существующие
символы в месте смены значения. Такие как:
* b - граница слова;
* B - не граница слова;
* A - начало строки;
* Z - конец строки;
* G - конец действия m//g.
Граница слова (b) - это мнимая точка между символами w и W. Внутри
класса символов 'b' обозначает символ backspace (стирания).
Метасимволы A и Z - аналогичны '^' и '$' но если началостроки '^' и
конец строки '$' действуют для каждой строки в многосторочной строке,
то A и Z обозначают начало и конец всей многосторчной строки.
Если внутри шаблона применяется группировка (круглые скобки) то номер
подстроки группы обозначается как 'цифра'.
Заметьте что за шаблоном в пределах выражения или блока эти группы
обозначаются как '$цифра'. Кроме этого существуют дополнительные
переменные:
* $+ - обозначает последнее совпадение;
* $& - все совпадение;
* $` - все до совпадения;
* $' - все после совпадения.
Пример:
$s = "Один 1 два 2 и три 3";
if ($s =~ /(d+)D+(d+)/)
{
print "$1n"; # Результат '1'
print "$2n"; # '2'
print "$+n"; # '2'
print "$&n"; # '1 два 2'
print "$`n"; # 'Один '
print "$'n"; # ' и три 3'
}
Perl версии 5 содержит дополнительные конструкции шаблонов:
* (?#комментарий) - комментарий в теле шаблона.
* (?:шаблон) - группировка как и '( )' но без обратной ссылки.
* (?=шаблон) - "заглядывание" вперед.
Например /w+(?=t)/ соответствует слову, за которым идет табуляция,
но символ 't' не включается в результат.
Пример:
$s = "1+2-3*4";
if ($s =~ /(d)(?=-)/) # Наити цифру за которой стоит '-'
{
print "$1n"; # Результат '2'
} else {
print "ошибка поискаn";
}
(?!шаблон) - "заглядывание" вперед по отрицанию.
Пример:
$s = "1+2-3*4";
if ($s =~ /(d)(?!+)/) # Наити цифру за которой не стоит '+'
{
print "$1n"; # Результат '2'
} else {
print "ошибка поискаn";
}
(?ismx) - "внутренние" модификаторы. Удобно применять в шаблонах, где
например нужно внутри шаблона указать модификатор.
Правила регулярных выражений
* Любой символ обозначает себя самого если это не метасимвол. Если
вам нужно отменить действие метасимвола то поставьте перед ним
''.
* Строка символов обозначает строку этих символов.
* Множество возможных символов (класс) заключается в квадратные
скобки '[]' это значит что в данном месте может стоять один из
указанных в скобках символ. Если первый символ в скобках это '^' -
значит не один из указанных символов не может стоять в данном
месте выражения. Внутри класса можно употреблять символ '-'
обозначающий диаппазон символов. Например a-z один из малых букв
латинского алфавита, 0-9 - цифра и т.д.
* Все символы, включая специальные можно обозначать с помощью ''
как в языке С.
* Альтернативные последовательности разделяются символом '|'
Заметьте, что внутри квадратных скобок это обычный символ.
* Внутри регулярного выражения можно указыват "подшаблоны", заключая
их в крунлые скобки и ссылаться на них как 'номер' Первая скобка
обозначается как '1'.
ControlStyle,
15.05.2006.
Регулярные выражения в Perl.
Регулярные выражения используются для нахождения шаблонов в строках.
Например, для того, чтобы найти в телефонной книге конкретное имя,
или,например, все имена, начинающиеся с буквы 'a'. Работа с
регулярными выражениями является одной из самых мощных и полезных, и в
тоже время самых сложных для понимания особенностей Perl. Надеемся,
что после прочтения этой статьи вы поймете, насколько это мощный и
удобный инструмент. Получив некоторый опыт вы сможете использовать эти
возможности с большой пользой для себя.
Операторы
Для работы с регулярными выражениями в Perl используются три оператора
- оператор сравнения (matching - m//), оператор подстановки
(substitution s///) и оператор перевода (translation - tr///).
Все три оператора используют переменную $_ по умолчанию, поэтому
дальше, пока не будут представлены операции =~ и !~, будем
пользоваться ею.
Оператор сравнения проверяет, подходит ли проверяемое выражение под
шаблон, и возвращает значение 1, если это так, и значение 0 в
противном случае. Запись этого оператора состоит из буквы m,
разделителя (чаще всего это косая линия - /, но в принципе это может
быть почти любой символ), шаблона и еще одного разделителя (такого же,
как и первый :).
Оператор сравнения
$_ = ;
if (m/hello/) {
print "hello usern";
}
if ($input{'siteurl'} =~ #http://#) {
print $input{'siteurl'};
}
В этом примере проверяется, есть ли в строке, полученной со
стандартного входа, слово 'hello'. Если это так (оператор m// вернет
значение 1), то на стандартный выход вернется фраза 'hello user'.
Примечание:вообще-то символ 'm' является необязательным, поэтому
оператор из этого примера может выглядеть просто как /hello/.
Оператор подстановки находит в строке все подстроки, удовлетворяющие
шаблону, и заменяет их некоторым другим значением. Запись этого
оператора состоит из буквы s, указывающей на то, что это собственно
оператор подстановки и исходного (что заменять) и подстановочного (на
что заменять) шаблонов, разделенных разделителями.
Оператор подстановки
$_ = 'My name is Fred';
# oh no, my name is Jonathan!
s/Fred/Jonathan/;
В этом примере в строке $_ все слова Fred будут изменены на Jonathan.
Оператор перевода также производит подстановку, но несколько другого
характера - он используется для замены отдельных символом некоторыми
другими (определенными) символами. Синтаксис этого оператора похож на
синтаксис оператора подстановки, с тем отличием, что во-первых он
очевидно начинается с букв tr, а между разделителями вставляются не
шаблоны, а группы символов, первая - исходные символы, вторая -
подстановочные, причем соответствующие символы должны стоять на
одинаковых позициях в своих группах - если вы хотите заменить,
например латинскую 'm' на кириллическую 'м', они должны стоять на
одинаковых местах: 'm' - в первой группе символов, 'м' - во второй.
Оператор перевода
$_ = 'hi.there, my.name.is.jonathan,';
tr/.,/ !/;
В этом примере все запятые будут изменены на восклицательные знаки, а
точки - на пробелы.
Модификаторы
Возможности каждого из этих операторов можно расширить при помощии
модификаторов. Модификаторы - это грубо говоря символы которые
дописываются к оператору (например, так - s/fred/Jonathan/i), говоря о
том, как ему нужно разбирать рабочее значение.
Модификаторы для оператора сравнения:
* g - находит все найденные подстроки;
* i - игнорирует регистр символов в строке;
* m - рассматривает строку как многострочное значение;
* s - рассматривает строку как однострочое значение;
* x - позволяет использовать расширенные регулярные выражения;
Модификаторы для оператора подстановки:
* e - вычисляет подстановочное выражение перед подстановкой;
* g - находит все найденные подстроки;
* i - игнорирует регистр символов в строке;
* m - рассматривает строку как многострочное значение;
* s - рассматривает строку как однострочое значение;
* x - позволяет использовать расширенные регулярные выражения.
Модификаторы
$_ = 'My name is Fred';
s/fred/Jonathan/i; # My name is Jonathan
s/jonathan/routine()/ie; # My name is [something]
Операции =~ и !~
Операции =~ и !~ позволяют использовать с операторами m//, s/// и
tr/// любые переменные, а не только $_, которая используется этими
операторами по умолчанию.
Оператор =~ выполняет те же функции, что и оператор присваивания '='
(в случае использования с операторами s/// и tr///) и оператор
сравнения 'eq' (при использовании с оператором m//).
Операция =~
$name = 'my name is Fred';
$name =~ s/fred/Jonathan/ig;
$string = 'hello world';
if ($string =~ /hello/i) {
print 'helloworlded in this string.';
}
Аналогично, операция !~ используется так же как и операция 'ne' (ее
написание подобно операции чисельного сравнения !=), используется
только с оператором сравнения и означает отрицание удовлетворения
шаблону.
Операция !~
$string = 'good';
if ($string !~ /bad/) {
print "hey, it's not too bad yet!";
}
Память
И напоследок - о возможности более удобно работать с результатами
обработки регулярных выражений, а именно о хранении их в отдельных
переменных. Такими переменными являются предопределенные $&, $`, $', и
набор переменных $1, $2, ..., $9.
Переменная $&
Эта переменная предназначена для хранения фрагмента строки, который
удовлетворил шаблону, заданному регулярным выражением. Это удобно в
таких случаях, как, например, если нужно найти число в строке, но
неизвестно, что это за число. Вот как это может выглядеть:
Эти переменные служат для хранения фрагментов, которые не
удовлетворили шаблону, а именно подстрок, которые стоят до и после
результата соответственно. Другими словами, после операции, например,
сравнения, значение исходой строки разделяется на три части - часть,
которая подошла под шаблон, и фрагменты, которые идут перед ней и
после нее. Эти части и помещаются в переменные $&, $` и $'
соответственно. (Обратите внимание на то, что в первой переменной -
обратная кавычка, а во второй - прямая). Посмотрим на предыдущий
пример.
$string = "error 404."
$string =~ m/d+/;
$number = $&; # $number содержит "404"
$before = $`; # $before содержит "error"
$after = $'; # $after содержит "."
Переменные $1..$9
Эти переменные служат для хранения фрагментов строки, которые
удовлетворили соответсвующим определенным фрагментам шаблона. В
шаблоне фрагменты выделяются при помощи скобок. Каждому фрагменту
выделяется номер в том порядке, в котором они расположены, и
соответствующая переменная будет содержать его значение.
$string = "this is to be uppercased";
$string =~ s/(upperw+)/uc($1)/;
# $string = "this is to be UPPERCASED"