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

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

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

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

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

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

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

Как они отличаются друг от друга, когда дело доходит до точки неудачи?

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

Ответ 1

Прежде чем прочесть этот ответ, вы должны быть знакомы с механизмом возврата, атомных групп и притяжательных квантификаторов. Вы можете найти информацию об этих понятиях и функциях в книге Friedl и следуя этим ссылкам: www.regular-expressions.info, 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): механизм regex встречает первый "c" и пытается использовать первый вариант и находит: caac, но подшаблон принудительно завершается с ошибкой. Затем механизм регулярных выражений (всегда с первого "c" ) пытается выполнить вторую альтернативу, третий вариант завершается успешно. (caaco)

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

(* SKIP)

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

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

(* PRUNE)

baabo caaco daado

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

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

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

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

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

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