Я не слышал точных терминов «срыгивать» или «отступать» раньше;Фраза, которая заменит их, - это «возврат», но «регургитация» выглядит так же хорошо, как любая фраза для «контента, который был предварительно принят до возврата назад».
Важная вещь дляВы понимаете, что большинство движков регулярных выражений возвращают : они ориентировочно принимают потенциальное частичное совпадение, пытаясь сопоставить все содержимое регулярного выражения.Если регулярное выражение не может быть полностью сопоставлено с первой попытки, то механизм регулярного выражения будет возвращать в одном из его совпадений.Он попытается сопоставить *
, +
, ?
, чередование или {n,m}
повторение по-другому и попытается снова.(И да, этот процесс может занять много времени.)
В первом примере используется жадный квантификатор. * Для поиска «чего угодно», ноль или более раз, после чего следуетбуквы "ф", "о", "о".Поскольку квантификатор является жадным, часть выражения. * Сначала съедает всю входную строку.На этом этапе общее выражение не может быть успешно выполнено, потому что последние три буквы ("f" "o" "o") уже были использованы ( кем? ).
Последние три буквы f
, o
и o
уже были использованы начальной частью .*
правила.Однако следующий элемент в регулярном выражении, f
, во входной строке ничего не осталось.Движок будет вынужден вернуть назад в исходное совпадение .*
и попытаться сопоставить все, кроме самого последнего символа.(Это может быть smart и возврат к принципу «все, кроме последних трех», потому что в нем три буквальных термина, но я не знаю подробностей реализации на этом уровне.)
Таким образом, устройство сравнения медленно отступает ( справа налево? ) по одной букве за раз, пока не произойдет регургитация самого правого вхождения "foo" ( что это значит? ), при котором
Это означает, что foo
имел ориентировочно , включая при совпадении .*
.Поскольку эта попытка не удалась, механизм регулярных выражений пытается принять на один символ меньше .*
.Если в этом примере было успешное совпадение до * .*
, то движок, вероятно, попытался бы сократить совпадение .*
(справа налево, как вы указали, потому что этожадный квалификатор), и если ему не удалось сопоставить все входные данные, то он мог бы быть вынужден переоценить то, что соответствовало до * .*
в моем гипотетическом примере.
указывает на совпадение, и поиск заканчивается.
Второй пример, однако, неохотен, поэтому он начинает с того, что сначала потребляет ( кем? ) "ничто".Потому что "foo"
Исходное ничто не потребляется .?*
, который потребляет минимально возможное количество из всего, что позволяет остальным регулярным выражениям совпадать.
не появляется в начале строки, он вынужден глотать ( кто глотает?)
Снова .?*
потребляет первый символ, после возврата напервоначальная ошибка сопоставления всего регулярного выражения с кратчайшим возможным совпадением.(В этом случае механизм регулярных выражений расширяет совпадение для .*?
слева направо, потому что .*?
неохотно.)
первая буква («х»), котораязапускает первое совпадение в 0 и 4. Наш тестовый жгут продолжает процесс до тех пор, пока входная строка не будет исчерпана.Он находит другое совпадение в 4 и 13.
В третьем примере не удается найти совпадение, поскольку квантификатор является притяжательным.В этом случае вся входная строка потребляется. * +, ( как? )
A .*+
будет потреблять как можно больше, а не будет возвращать для поиска новых совпадений, когда регулярное выражение в целом не может найти совпадение. Поскольку притяжательная форма не выполняет возврат, вы, вероятно, не увидите много вариантов использования с .*+
, а скорее с классами символов или аналогичными ограничениями: account: [[:digit:]]*+ phone: [[:digit:]]*+
.
Это может значительно ускорить сопоставление регулярных выражений, потому что вы говорите механизму регулярных выражений, что он никогда не должен возвращаться к потенциальным совпадениям, если входные данные не совпадают. (Если бы вам пришлось писать весь соответствующий код вручную, это было бы похоже на то, чтобы никогда не использовать putc(3)
для «возврата» входного символа. Это было бы очень похоже на простой код, который можно написать с первой попытки. За исключением движки регулярных выражений намного лучше, чем один символ push-back, они могут перематывать все назад до нуля и пытаться снова.:)
Но это больше, чем потенциальные ускорения, это также позволяет вам писать регулярные выражения, которые точно соответствуют тому, что вам нужно. У меня возникают проблемы с простым примером :), но написание регулярного выражения с использованием квантификаторов «притяжательный против жадных» может дать вам разные совпадения, и один или другой может быть более подходящим.
не оставляя ничего, чтобы удовлетворить
"Фу" в конце
выражение. Используйте притяжательное
квантификатор для ситуаций, когда вы
хочу захватить все что-то без
когда-либо отступать ( что означает отступать? ); это превзойдет
«Отступать» в данном контексте означает «возвращение» - отбрасывать предварительное частичное совпадение, чтобы попробовать другое частичное совпадение, которое может или не может быть успешным.
эквивалентный жадный квантификатор в
случаи, когда совпадения нет
немедленно найден.