Язык программирования Perl

Извлечение соответствий


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

  • в переменную $` помещается часть строки до найденного соответствия;
  • в переменную $& помещается часть строки, соответствующая образцу;
  • в переменную $' помещается часть строки после найденного соответствия;
  • в переменную $+ помещается последнее найденное совпадение для последнего шаблона в скобках.

Если поиск окончился неудачей, то этим переменным новые значения не присваиваются. Посмотрим на примере, что сохранится в этих переменных после поиска такого соответствия:

$htm= "<A HREF='http://regexp.ru/'>Регулярные выражения</A>"; $htm =~ m|HREF=["'](\S+?)["']>|; # поиск URL сайта

При успешном совпадении с шаблоном в специальные переменные будут помещены такие значения:

$` = '<A ' $& = 'HREF='http://regexp.ru/'>' $' = 'Регулярные выражения</A>' $+ = 'http://regexp.ru/'

Значениями этих переменных можно пользоваться при успешном сопоставлении с образцом, например:

print $& if $text =~ m/$pattern/; # выведет соответствие

В регулярном выражении можно указать, что при успешном сопоставлении строки с шаблоном найденные соответствия нужно сохранить для дальнейшей обработки. С этой целью запоминаемые части шаблона нужно заключить в круглые скобки. Это также называется захватом значений. Найденные совпадения для всех заключенных в скобки частей шаблона будут доступны через специальные переменные с именами $1, $2 и так далее. Составим регулярное выражение для поиска и сохранения в служебных переменных информации о сайте в том же тексте:

$pattern = q|HREF=["'](\S+?)["']>([^<]+?)</A>|; # шаблон $htm =~ m/$pattern/; # поиск соответствия в $htm # в $1 = 'http://regexp.ru/' # в $2 = 'Регулярные выражения'

Сохраненные совпадения доступны и во время обработки регулярного выражения, но через переменные с именами \1, \2 и так далее. Эти переменные называются обратными ссылками (backreference) на найденные соответствия. Так, например, можно найти два одинаковых слова, стоящих в тексте друг за другом через пробелы (возможно, по ошибке):

my $string = "Уже скоро скоро наступит весна!"; my $pattern = '(\S+)\s+\1'; # (\S+) сохранит значение 'скоро' в \1 $string =~ m/$pattern/; # соответствие: 'скоро скоро'

Операция сопоставления, употребленная в списочном контексте, возвращает список найденных соответствий, для которых было предусмотрено сохранение значений. Поэтому удобно сохранять найденные значения в массиве или в списке скалярных переменных. Например, извлечем из текстовой строки последовательность цифр, похожую на время:

my $text = 'Начало в 12:25:00.'; # строка с данными my $pattern = '(\d\d):(\d\d):(\d\d)'; # образец для поиска my @time = $text =~ m/$pattern/; # сохраним в массиве my ($hh, $mm, $ss) = $text =~ m/$pattern/; # и в списке

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



Содержание раздела