Утверждения

Утверждения — это проверки касательно символов, идущих до или после текущей позиции сопоставления, ничего при этом не поглощая (никакие символы исходного текста не ставятся в соответствие утверждениям). Наиболее простые варианты утверждений, например, \b, \B, \A, \Z, \z, ^ и $ рассмотрены в escape-последовательности. Более сложные утверждения записываются как подмаски. Утверждения бывают двух видов: те, которые анализируют текст, следующий после текущей позиции (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 захватывающих подмасок.

add a note add a note

User Contributed Notes 1 note

up
-4
daevid at daevid dot com
11 years ago
removes // comments but NOT the stuff after http://

$sBlob = preg_replace("@\s*(?<!:)//.*?$@m",'',$sBlob);

Although, as Sean Greenslade pointed out, it will fail in this EDGE case since the comments are within quotes, but who does that anyways?

"Lol slashes // are // fun";
To Top