Утверждения — проверка символов, которые идут до или после текущей позиции сопоставления, которая фактически не включает никаких символов (символы входной строки не сопоставляются с утверждениями). Наиболее простые варианты утверждений, например \b, \B, \A, \Z, \z, ^ и $, рассматривает раздел «Экранирующие последовательности». Более сложные утверждения записываются как подшаблоны. Утверждения бывают двух видов: те, которые анализируют текст, следующий после текущей позиции (look ahead), и идущий перед ней (look behind).
Сопоставление подшаблонов, которые содержат утверждение, выполняют обычным
образом, за исключением того, что текущая позиция не изменяется.
Утверждения касательно последующего текста
начинаются с (?= для положительных утверждений и с (?! для отрицающих
утверждений. Например,
\w+(?=;)
совпадает со словом, за которым следует символ «;», но при этом сама
точка с запятой в совпадение не включается. А
foo(?!bar)
соответствует любому появлению «foo», после которого не идёт «bar».
Заметим, что похожий шаблон
(?!foo)bar
не будет искать вхождение «bar», которому предшествует любая
строка за исключением «foo». Но, тем не менее, он будет соответствовать
любым вхождениям подстроки «bar», поскольку условие (?!foo) всегда
true
, если следующие три символа — «bar». Для получения желаемого
результата необходимо воспользоваться второй категорией утверждений.
Утверждения касательно предшествующего текста
начинаются с (?<= для положительных утверждений и (?<!
для отрицающих. Например,
(?<!foo)bar
найдёт вхождения «bar», которым не предшествует «foo». Сами
утверждения «назад» ограничены так, чтобы все подстроки, которым
они соответствуют, имели фиксированную длину. Но, Если
используются несколько альтернатив, они не обязаны иметь одинаковую
длину. Таким образом шаблон
(?<=bullock|donkey)
корректен, но
(?<!dogs?|cats?)
вызовет ошибку во время компиляции. Ветки, которые соответствуют
строкам разной длины, разрешены только на верхнем уровне утверждений
касательно предшествующего текста. Это расширение относительно
Perl 5.005, который требует чтобы все ветки соответствовали строкам
одинаковой длины. Такое утверждение как
(?<=ab(c|de))
не корректно, поскольку верхний уровень маски может соответствовать
строкам разной длины, но его можно преобразовать к корректному шаблону,
используя альтернативы на верхнем уровне:
(?<=abc|abde)
Утверждения касательно предшествующего текста реализованы так,
что для каждой альтернативы текущая позиция временно переносится
назад, на фиксированную ширину, после чего выполняется поиск
соответствия условию. Если перед текущей позицией недостаточно
символов, поиск соответствия терпит неудачу. Утверждения назад в сочетании
с однократными подшаблонами удобны для поиска
в конце строки; соответствующий пример приведён в конце раздела
«Однократные подшаблоны».
Несколько утверждений (разных типов) могут присутствовать в
утверждении, например:
(?<=\d{3})(?<!999)foo
совпадает с подстрокой «foo», которой предшествуют три цифры,
отличные от «999». Следует понимать, что каждое из утверждений
проверяется относительно одной и той же позиции в обрабатываемом
тексте. Вначале выполняется проверка того, что предшествующие три символа —
это цифры, затем проверяется, чтобы эти же цифры не являлись
числом 999. Приведённый выше шаблон не соответствует подстроке
«foo», которой предшествуют шесть символов, первые три из которых —
цифры, а последние три не образуют «999». Например, он не
соответствует строке «123abcfoo», в то время как шаблон
(?<=\d{3}...)(?<!999)foo
соответствует.
В этом случае анализируются предшествующие шесть символов на предмет того, чтобы первые три из них были цифрами, а последние три не образовали «999».
Утверждения могут быть вложенными, причём в произвольных сочетаниях:
(?<=(?<!foo)bar)baz
соответствует подстроке «baz», которой предшествует «bar»,
перед которой, в свою очередь, нет «foo», а
(?<=\d{3}...(?<!999))foo
—
совершенно другой шаблон, соответствующий подстроке «foo»,
которой предшествуют три цифры и три произвольных символа, отличных
от «999».
Утверждающие подшаблоны — незахватывающие и неповторяемые, поскольку бессмысленно повторять одно и то же несколько раз. Если в утверждении произвольного типа находится захватывающий подшаблон, он нумеруется в той же последовательности, что и все остальные захватывающие подшаблоны, но захват соответствующих значений происходит только для положительных утверждений, поскольку для отрицающих это не имеет смысла.
В утверждениях обрабатывается не более 200 захватывающих подшаблонов.