Утверждения

Наверх  Предыдущий  Следующий

Утверждение - это проверка символов до или после текущей позиции сравнения, которая сама символов не потребляет. Простые утверждения такие как: \b, \B, \A, \Z, \z, ^ и $ были обсуждены выше. Более сложные утверждения кодируются в виде подшаблонов. Утверждения бывают двух видов: проверяющие символы после текущей позиции сравнения (впередсмотрящие) и проверяющие символы до текущей позиции сравнения (назадсмотрящие).

 

Подшаблон, являющийся утверждением, сравнивается со строкой обычным образом, за исключением того, что он не приводит к изменению текущей позиции. Впередсмотрящие утверждения начинаются с "(?=" для позитивных утверждений и с "(?!" для негативных утверждений. К примеру, шаблон

\w+(?=;)

совпадет со словом, за которым идет точка с запятой, при этом сама точка с запятой в сравнение не включается, а шаблон

foo(?!bar)

совпадет с каждым появлением "foo" за которым не следует "bar". Заметьте, что похожий шаблон

(?!foo)bar

не сможет обнаружить наличие "bar" перед которым находится не "foo", вместо этого он будет обнаруживать все "bar", так как утверждение (?!foo) всегда истинно если последующие три символа "bar". Для достижения нужного эффекта следует использовать назадсмотрящие утверждения.

 

Назадсмотрящие утверждения начинаются с "(?<=" для позитивных утверждений и с "(?<!" для негативных утверждений. К примеру, шаблон

(?<!foo)bar

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

(?<=bullock|donkey)

разрешен, в то время как

(?<!dogs?|cats?)

вызовет ошибку во время компиляции. Ветви, совпадающие со строками разной длины, допустимы только не "верхнем уровне" назадсмотрящего утверждения. По сравнению с Perl 5.005 это является расширением, так как в нем требовалось, чтобы все ветви совпадали со строками одной длины. Утверждение

(?<=ab(c|de))

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

(?<=abc|abde)

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

 

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

(?<=\d{3})(?<!999)foo

совпадет с "foo" перед которым стоят три цифры, но не "999". Более того, утверждения могут быть вложеными. Например

(?<=(?<!foo)bar)baz

совпадет с "baz" перед которым стоит "bar", перед которым, в свою очередь не стоит "foo".

 

Подшаблоны, являющиеся утверждениями, не участвуют в захвате подстрок и не могут повторяться, так как нет смысла проверять одно и то же утверждение несколько раз. Если внутри утверждения находятся подшаблоны, захватывающие подстроки, они будет считаться обычным образом для использования в обратных ссылках. Захват подстрок имеет смысл для позитивных утверждений, и совершено бессмысленный для негативных.

 

Утверждения учитываются в ограничении на 200 подшаблонов в скобках.