Может ли кто-нибудь объяснить процесс, в котором двигатель регулярного выражения соответствует (aa)+\1
против aaaaaa
? Я знаю, что есть процесс, называемый backtracking, когда вы используете +
или *
, но я не уверен, как он работает в этом примере.Как регулярное выражение "(aa) + 1" соответствует "aaaaaa"?
ответ
Когда вы кладете квантор вне группы захвата, он не фиксирует всю строку, сопоставляемую с этим паттерном с квантификатором. Это скорее соответствует только последнему повторению, которое соответствует шаблону.
Итак, (aa)+
не фиксирует aaaa
в группе захвата, а только последнюю пару - aa
, так что он может удовлетворять остальным шаблонам регулярных выражений.
Так, с (aa)+\1
, шаблон соответствует первому - aaaa
, а затем обратная ссылка \1
соответствует захваченной группе - aa
. Таким образом, соответствует строка - aaaaaa
. Не (aa)+
не будет соответствовать всем a's
, потому что тогда ничего не останется, чтобы соответствовать \1
.
Вот Распад регулярное выражение (aa)+\1
:
(aa)+
матчи первых двухaa
в строке. Оставшаяся строка -aaaa
.- Подходит под
(aa)+
, поэтому продолжается дальшеaa
. Оставшаяся строка -aa
. - Опять
(aa)+
может соответствовать оставшейся строке. Таким образом, он соответствует следующемуaa
. Оставшаяся строка -""
. Помните, что кванторы по умолчанию действуют жадные. Они будут соответствовать как можно больше. - Теперь
(aa)+
не может быть больше. - Следующая картинка:
\1
. Но нечего сравнивать. - Backtrack последний образец, соответствующий
(aa)+
. Оставшаяся строка -"aa"
. - Теперь
\1
снова пытается соответствовать, и он успешно соответствуетaa
, так как это то, что сейчас находится в группе захвата 1 st.
Ссылки:
Калькулятор +
означает «1 или более». \1
относится к захваченной группе, то же самое относится к квантификатору. Так эффективно, это говорит «группа аа, 1 или более раз, а затем еще один раз». Это то же самое, что «2 или более раз».
Таким образом, регулярное выражение может быть яснее, как это: /(aa){2,}/
Поскольку aaaaaa
три Множества aa
группы, то регулярное выражение соответствует строке.
Это не объясняет * как * выполняется сопоставление (т. backtracking), что и требовал ОП. – Bakuriu
Сценарий:
aa # the group is matched
aaaa # the group is repeated once, cause the + quantifier
aaaaaa # the group is repeated once again, always cause
# the + quantifier (and because it is greedy and take all it can.)
# But since all the characters are eaten, and there is \1
# the pattern will fail.
aaaa # the regex engine must backtrack to try another way because of \1
aaaaaa # you are arrived! (the 2 last "a" are for the \1
Вы можете проверить это поведение с помощью притяжательного ква ntifier (++), которые запрещают обратные трассировки:
(aa)++\1 # will never match
Спасибо за отличный ответ! Не могли бы вы также прокомментировать, что произойдет, если я это сделаю: '(aa +) \ 1', где я помещаю квантификатор внутри группы захвата? – bodacydo
Возможно, я должен задать еще один вопрос: «Как' (aa +) \ 1' отличается от '(aa) + \ 1'? – bodacydo
@bodacydo:' (aa +) \ 1' будет соответствовать вашей заданной строке, с 'aaa' для группа квантования .Квантификатор + берет все 'a' строки, а механизм regex будет возвращать символ по символу до тех пор, пока шаблон не будет соответствовать. –