Глаголы, которые действуют после возврата и неудачи

Я недавно читал в PCRE - (Perl-совместимые регулярные выражения) документация и наткнулся на некоторые интересные трюки с регулярными выражениями. Поскольку я продолжал читать и исчерпывать себя, я остановился из-за некоторой путаницы в связи с использованием нескольких из (*...) узоры.

Мой вопрос и путаница связаны с (*PRUNE) а также (*FAIL)

Теперь для справки (*SKIP) действует как (*PRUNE), за исключением того, что, если шаблон не зафиксирован, продвижение вперед на удар не к следующему символу, а к позиции в предмете, где (*SKIP) был встречен.

В документации говорится, что (*PRUNE) приводит к сбою сопоставления в текущей начальной позиции субъекта, если остальная часть шаблона не совпадает. И говорится (*FAIL) синоним (?!) отрицательное утверждение. Вызывает сбой сопоставления в заданной позиции в шаблоне.

Так в основном (*FAIL) ведет себя как ошибочное отрицательное утверждение и является синонимом (?!)

А также (*PRUNE) приводит к сбою сопоставления в текущей начальной позиции в субъекте, если существует более поздний сбой сопоставления, который вызывает возврат к нему.

Чем они отличаются, когда дело доходит до провала?

Кто-нибудь может привести примеры того, как они реализованы и используются правильно?

1 ответ

Решение

Прежде чем читать этот ответ, вы должны быть знакомы с механизмом возврата, атомными группами и собственническими квантификаторами. Вы можете найти информацию об этих понятиях и особенностях в книге Фридла и по следующим ссылкам: http://www.regular-expressions.info/, http://www.rexegg.com/

Все тесты были сделаны с помощью глобального поиска (с preg_match_all() функция).

(*ПОТЕРПЕТЬ ПОРАЖЕНИЕ)

baabo caaco daado

caac(*FAIL)|aa.|caaco|co

[0] => aab
[1] => caaco
[2] => aad

(*FAIL) вызывают точно такое же поведение, что и "плохой персонаж" в шаблоне. Если вы замените его буквой "R", вы получите точно такой же результат: caacR|aa.|caaco|co, Чтобы быть более общим, вы действительно можете заменить (*FAIL) "всегда неудачным подшаблоном" вроде: (?!), (?=a(?<!a))...

a (first from "baabo"): Неудивительно, что первый результат найден по второму варианту. (aab)

c (first): Движок регулярных выражений встречает первую букву "с" и пробует первый вариант и находит: caac, но подшаблон вынужден потерпеть неудачу. Затем движок регулярных выражений (всегда из первой буквы "с") пробует второй вариант, который терпит неудачу, третий вариант успешно. (caaco)

a (first from "daado"): третий результат находится по второму варианту. (aad)

(*ПРОПУСКАТЬ)

baabo caaco daado

caa(*SKIP)c(*FAIL)|aa.|caaco|co

[0] => aab
[1] => co
[2] => aad

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

a (first from "baabo"): первый результат находится по второму варианту. (aab)

c (first): поиск движка regex caac как в первом случае, то не удается (причина (*FAIL) глагол), возвращает обратно ко второму "c", но не разрешается возвращать к символам, которые были ранее сопоставлены ("caa") перед (*SKIP) глагол.
c (second): Теперь движок регулярных выражений всегда пробует первый вариант, но в этой новой позиции, и терпит неудачу, так как после него идет "o", а не "a", затем он возвращается к этому второму "c". Обратите внимание, что в этом случае эти символы не используются как раньше, потому что дочерний шаблон не прошел до того, как достиг (*SKIP) глагол. Вторая альтернатива проверена и дает сбой (не начинается с "с"). Третий вариант тоже терпит неудачу, потому что следующий символ - "o", а не "a". Четвертый вариант удачен и дает второй результат. (co)

a (first from "daado"): третий результат находится по второму варианту. (aad)

(*ЧЕРНОСЛИВ)

baabo caaco daado

caa(*PRUNE)c(*FAIL)|aa.|caaco|co

[0] => aab
[1] => aac
[2] => aad

Этот глагол отличается от (*SKIP) потому что он не запрещает использовать все предыдущие совпавшие символы, но пропускает первый совпавший символ в подшаблоне (или запрещает запускать подшаблон), если подшаблон потерпит неудачу позже.

a (first from "baabo"): первый результат находится по второму варианту. (aab)

c (first): поиск движка regex caac как и в первом случае, затем происходит сбой, но теперь возвращается к первому "a" из "caaco", поскольку первый "c" пропускается.
a (first from "caaco"): первая альтернатива испробована и провалена, вторая успешна и дает второй результат. (aac)

a (first from "daado"): третий результат находится по второму варианту. (aad)

Другие вопросы по тегам