Почему повторяющаяся группа захвата возвращает эти строки?

#python #regex

#python #регулярное выражение

Вопрос:

Кто-нибудь может объяснить, почему following возвращает ‘cc’?

 >>> re.match('(..) ', 'aabbcc').group(1)
'cc'
  

Мне сказали это, потому что это помещает каждое совпадение в группу (1), так что последнее совпадение — «cc». Это правда?

Тогда как объяснить следующее?

 >>> re.match('(..) (...)', 'aabbcc').group(1)
'aa'
  

Ответ №1:

Повторяющаяся группа захвата: номер группы остается неизменным

Группа, определенная (..) , является группой 1. Квантификатор повторяет это. Каждый раз, когда движок может повторить группу (сопоставляя два символа), группа 1 перезаписывается.

  • Когда движок начинает соответствовать, он записывает aa в группу 1
  • Затем она записывается bb в группу 1
  • Затем она записывается cc в группу 1.

Когда вы проверяете группу 1, движок возвращает cc . Все остальные захваты теряются.

(Исключением является .NET engine, который также возвращает cc , но также позволяет проверять промежуточные захваты благодаря объекту CaptureCollection. Она будет содержать aa , bb и cc .)

С (..) (...) , Почему группа 1 содержит aa ? Отслеживание возврата!

Чтобы понять это, нам снова нужно проследить путь механизма регулярных выражений.

  • Еще раз, когда движок начинает соответствовать, он записывает aa в группу 1
  • Опять же, он повторяет (..) группу и записывает bb в группу 1
  • Опять же, он повторяет (..) группу и записывает cc в группу 1
  • Теперь движок пытается сопоставить (...) . Сбой: не осталось символов для использования.
  • Движок выполняет возврат как в строке, так и в шаблоне регулярных выражений. Означает один или несколько раз, а мы сопоставляли .. три раза, так что мы можем отказаться от одного или даже двух. На этом этапе движок выдает последнее совпадение с количественно определенной (..) группой, которое является cc . Мы возвращаемся к тому, когда была группа 1 bb .
  • Движок снова пытается выполнить сопоставление (...) . Осталось всего два символа: cc , поэтому снова происходит сбой.
  • Движок выполняет возврат, отказываясь от последнего совпадения с количественно определенной (..) группой, которая является bb . На этом этапе aa снова используется группа 1.
  • Движок снова пытается выполнить сопоставление (...) . Это успешно: группа 2 является bbc , а группа 1 является aa

Ссылка

Комментарии:

1. К вашему сведению, я добавил подробное объяснение внутренних компонентов движка для (..) (...) случая. Также настоятельно рекомендую вам прочитать статью «Кровавые подробности» по ссылке. 🙂

2. Решил удалить мою, не хотелось писать историю.

3. @hwnd Да, довольно интересно понять, как это работает, но, как вы говорите, вам нужно написать всю историю движка. 🙂

4. Привет, Deqing, я добавил много деталей, поэтому, пожалуйста, дайте мне знать, если что-то неясно. 🙂