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

       

Квантификаторы, их "жадность" и ее ограничение


Ознакомимся с квантификаторами, также именуемыми числителями или повторителями. Если после подшаблона стоит квантификатор, то этот шаблон может повторяться столько раз, сколько указыват этот квантификатор. Например, шаблон a{0,4} соответствует нулю, одной, двум, трем и четырем буквам "a", идущим подряд.

Соответствие нулю каких-то символов означает соответствие пустой подстроке. Если максимальный параметр не ограничен, то его можно опустить: шаблон a{1,} соответствует последовательности из одной и более букв "а". Шаблон a{3} соответствует ровно трем подряд буквам a, это то же, что и шаблон aaa.

В Perl есть ограничение на максимальное значение квантификатора: 32766. Это связано с тем, что применение квантификаторов требует запоминания состояний, чтобы в последующем в случае неудачи поиска вернуться и попробовать варианты с другим числом повторений. Этот вопрос мы рассмотрим позднее.

Некоторые числители используются так часто, что для них сделали краткие формы записи:

  • a* - это нуль или больше символов a: a{0,};
  • a+ - это один или больше символов a: a{1,};
  • a? - это нуль или один символ a: a{0,1}.

Квантификаторы имеют высокий приоритет, поэтому шаблон bil+ing соответствует символам bi, после которых идет одна или больше букв l и далее последовательность ing. Если вы хотите, чтобы квантификатор соответствовал последовательности символов или группе подшаблонов, то эту конструкцию надо взять в скобки:

(bil)+ing соответстсвует строкам biling bilbiling bilbilbiling и т.д.

По умолчанию, алгоритм работы квантификаторов таков, что они пытаются захватить как можно больше текста, который им соответствует. Например, в переменной $text имеем текст

<b>Текст выделен жирным шрифтом.</b> Простой текст <b>Это опять жирный</b>

Если применить к этому тексту регулярное выражение <b>.+</b>: $text =~ /<b>.+</b>/ то оно будет соответствовать всему этому тексту, а не фрагменту <b>Текст выделен жирным шрифтом.</b>

Аналогично, в шаблоне

\w*a

примененном к строке

abcabcaaaaa

подшаблон \w* будет соответствовать подстроке

abcabcaaaa

(без последней буквы a), а не подстроке

abca

или

abcabca

Имеется способ заставить квантификаторы захватывать как можно меньше текста, для этого после такого квантификатора надо поставить знак вопроса: "?". Например:

a+?

соответствует минимуму из одной и более букв "a". Если этот шаблон применить к строке

bbbaaaabbb

то такой минимальный квантификатор захватит первую попавшуюся букву а, после чего оператор поиска закончит работу, вернув число 1.

В шаблоне

a*?

минимальный квантификатор удовлетворится нулем символов a, а это значит, что совпадение будет найдено в любом месте, даже после истинного конца строки! Оператор

print "a" =~ /\za*/;

напечатает 1.

Вот другие примеры минимальных квантификаторов:

\w? (abc){3,5}?



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