2013-08-24 2 views
7

Может ли кто-нибудь объяснить процесс, в котором двигатель регулярного выражения соответствует (aa)+\1 против aaaaaa? Я знаю, что есть процесс, называемый backtracking, когда вы используете + или *, но я не уверен, как он работает в этом примере.Как регулярное выражение "(aa) + 1" соответствует "aaaaaa"?

ответ

14

Когда вы кладете квантор вне группы захвата, он не фиксирует всю строку, сопоставляемую с этим паттерном с квантификатором. Это скорее соответствует только последнему повторению, которое соответствует шаблону.

Итак, (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.

Ссылки:

+0

Спасибо за отличный ответ! Не могли бы вы также прокомментировать, что произойдет, если я это сделаю: '(aa +) \ 1', где я помещаю квантификатор внутри группы захвата? – bodacydo

+1

Возможно, я должен задать еще один вопрос: «Как' (aa +) \ 1' отличается от '(aa) + \ 1'? – bodacydo

+1

@bodacydo:' (aa +) \ 1' будет соответствовать вашей заданной строке, с 'aaa' для группа квантования .Квантификатор + берет все 'a' строки, а механизм regex будет возвращать символ по символу до тех пор, пока шаблон не будет соответствовать. –

4

Калькулятор + означает «1 или более». \1 относится к захваченной группе, то же самое относится к квантификатору. Так эффективно, это говорит «группа аа, 1 или более раз, а затем еще один раз». Это то же самое, что «2 или более раз».

Таким образом, регулярное выражение может быть яснее, как это: /(aa){2,}/

Поскольку aaaaaa три Множества aa группы, то регулярное выражение соответствует строке.

+0

Это не объясняет * как * выполняется сопоставление (т. backtracking), что и требовал ОП. – Bakuriu

4

Сценарий:

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