Регулярные выражения Perl и их применение


Группировка элементов шаблона


Мы уже применяли захватывающие и просто группирующие скобки. Рассмотрим еще некоторые тонкости.

Как работают группирующие скобки с квантификаторами? Например, что захватят в переменную $1 скобки в регулярном выражении 'abc' =~ /(\w)*/ ? Это выражение похоже на (\w*), которое в переменную $1 захватит все три символа, но алгоритм его работы иной. Скобки в шаблоне (\w)* захватят последний символ - c. Для тех, кто впервые с этим сталкивается, это кажется непонятным. Это работает так: сначала \w совпадет с буквой a, затем квантификатор * будет заставлять повторяться всю внутрискобочную конструкцию снова и снова, насколько это возможно, оставляя при этом сохраненные состояния. При возвратах, когда происходит выход за открывающую захватывающую скобку, соответствующая ей нумерованная переменная становится неопределенной (перестает существовать). Если же при возврате происходит вход внутрь захватывающих скобок, то при следующем выходе за закрывающую скобку произойдет коррекция значения этой нумерованной переменной. Механизм работы с нумерованными переменными такой: при встрече открывающей скобки при движении вправо в структуре данных для соответствующей нумерованной переменной запоминается адрес позиции в результирующем тексте, где она начинается, а при выходе за закрывающую захватывающую скобку запоминается адрес позиции, где значение этой переменной заканчивается. Таким образом, нумерованные переменные не копируют фрагменты найденного текста, а просто ссылаются на них.

В нашем случае выражение \w повторится трижды, захватывая каждый раз следующую букву, и в конце концов захваченной окажется буква c. Мы получаем интересный тактический прием захвата последнего фрагмента текста, который соответствует заданному подшаблону. Я думаю, вы уже можете догадаться, как в общем случае можно захватить такой фрагмент текста, который стоит на n-ном месте с начала или конца ряда таких фрагментов. Например, чтобы захватить предпоследний символ, надо записать

/(\w)*\w/

А как бы стал работать этот шаблон, если бы квантификатор был минимальным? В этом случае

'abc' =~ /(\w)*?/;




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



Книжный магазин