Читаем Язык программирования Perl полностью

Для наиболее часто встречающихся квантификаторов предусмотрены удобные односимвольные сокращения:

* повторяется 0 или более раз: то же, что {0,} ? повторяется не более 1 раза: то же, что {0,1} + повторяется как минимум 1 раз: то же, что {1,}

Составим регулярное выражение с использованием односимвольных квантификаторов, чтобы найти в тексте "идентификатор, перед которым могут стоять пробельные символы и за которым стоит хотя бы один из перечисленных знаков препинания":

m/\s*\w+[-.,;?]+/ # соответствует, например: ' count--;'

Если квантификатор нужно применить к нескольким шаблонам, то нужно сгруппировать шаблоны, заключив их в круглые скобки. Составим регулярное выражение для поиска IP-адреса, которое находит число, состоящее из одной цифры и более (\d+), за которой может стоять точка (\.?), причем эта последовательность повторяется ровно четыре раза ({4}):

$pattern = '(\d{1,3}\.)\d{1}'; # шаблон для IP-адреса $text = 'address=208.201.239.36,site=www.perl.com'; $text =~ m/$pattern/; # соответствие: '208.201.239.36'

Программисты шутят: "При составлении шаблона главное, чтобы регулярное выражение соответствовало тому, что нужно, и не соответствовало тому, что не нужно". В следующем примере мы будем искать "более одного символа, за которыми идет буква 'й' и пробел", ожидая, что будет найдено слово 'Какой '. Но нас ожидает неприятный сюрприз:

my $text = 'Какой хороший компакт-диск!'; $text =~ /.+й\s/; # жадный квантификатор # найдено соответствие: 'Какой хороший '

Это произошло потому, что по умолчанию квантификаторы подразумевают максимальную последовательность символов, соответствующих указанному шаблону. Такое поведение квантификаторов называется "жадным" (greedy quantifier). Чтобы заставить квантификатор вести себя не "жадно", а "лениво" (lazy quantifier), нужно поставить сразу после него символ '?'. Тогда квантификатор будет описывать минимальную последовательность символов, соответствующих образцу. Исправленный с учетом этого образец найдет то, что нужно:

$text =~ /.+?й\s/; # ленивый квантификатор # найдено соответствие: 'Какой '

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

Часто нам бывает небезразлично, в каком месте содержимое строки совпадет с шаблоном. Мы бы хотели уточнить: "в начале строки", "в конце слова" и так далее. Для того чтобы более точно задать положение в тексте, где должно быть найдено соответствие, в регулярных выражениях можно указывать так называемые утверждения. Утверждение (assertion) не соответствует какому-либо символу, а совпадает с определенной позицией в тексте. Поэтому их можно воспринимать как мнимые символы нулевого размера. Чаще всего используются следующие утверждения (другие приведены в таблице 8.1):

^ позиция в начале строки $ позиция в конце строки (или перед \n в конце строки) \b граница слова: позиция между \w и \W или \W и \w \B любая позиция, кроме границы слова \b

Вот пример шаблонов поиска, где уточняется, что нужно проверить наличие числа в определенном месте строки:

$log = '20060326 05:55:25 194.67.18.73 ... 200 797'; print "Число в начале\n" if $log =~ /^\d+/; print "Число в конце\n" if $log =~ /\d+$/;

Утверждение, которое используется для фиксирования части образца относительно положения в строке, иногда называется якорем (anchor). Якори применяются, чтобы указать, в каком именно месте строки нужно искать соответствие образцу.

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

[x]. в переменную $` помещается часть строки до найденного соответствия;

[x]. в переменную $& помещается часть строки, соответствующая образцу;

[x]. в переменную $' помещается часть строки после найденного соответствия;

[x]. в переменную $+ помещается последнее найденное совпадение для последнего шаблона в скобках.

Перейти на страницу:

Похожие книги