Глаголы, которые действуют после возврата и неудачи
Я недавно читал в 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
)