Как работает атомарная группа внутри положительного взгляда назад?

Я не понимаю, почему регулярное выражение (?<=i:(?>\D*))\d не соответствует строке i:>1.

Как я это понимаю:

  • в индексе 0: просмотр назад i не будет соответствовать
  • в индексе 1: просмотр назад i: не будет соответствовать
  • в индексе 2: просмотр назад i:(?>\D*) будет соответствовать i:, но \d после просмотра назад не будет соответствовать >
  • в индексе 3: просмотр назад i:(?>\D*) будет соответствовать i:>, а \d после просмотра назад будет соответствовать 1 -> регулярное выражение удовлетворено

person AXO    schedule 03.01.2018    source источник
comment
Я знаю, что это сработает, если я заменю атомарную группу (?>\D*) на \D*, но я хочу знать, что происходит с атомарной группой. Это упрощенная версия более сложного регулярного выражения, с которым у меня возникла проблема.   -  person AXO    schedule 04.01.2018
comment
Проблема здесь в том, что просмотр назад реализован таким образом, что (?>\D*) выполняется до i:, а i: сопоставляется с \D*, а так как он находится внутри атомарной группы, возврат назад невозможен.   -  person Wiktor Stribiżew    schedule 04.01.2018
comment
@WiktorStribiżew lookbehind реализован таким образом, что ‍‍(?>\D*) выполняется до i:, спасибо, но почему они это сделали? Это где-то задокументировано?   -  person AXO    schedule 04.01.2018
comment
Единственная ссылка, которую я могу найти, это один из ответов Коби.   -  person Wiktor Stribiżew    schedule 04.01.2018


Ответы (1)


См. Пособие по регулярным выражениям: подробные решения на восьми языках программирования:

.NET позволяет вам использовать что угодно внутри ретроспективного просмотра, и на самом деле оно будет применять регулярное выражение справа налево. И регулярное выражение внутри ретроспективного просмотра, и текст темы сканируются справа налево.

Шаблон (?<=i:(?>\D*))\d не соответствует шаблону 1 в i:>1, потому что атомарная группа (?>\D*) предотвращает возврат к своему шаблону. i: (на самом деле, :, а затем i сопоставляются) сопоставляется с \D*, и тогда нет возможности повторно сопоставить i:, так как атомарная группа не допускает возврата.

Вы также можете видеть, что (?<=i:(?>[^:\d]*))\d будет соответствовать 1 в i:>1, потому что здесь [^:\d]* соответствует любому символу, кроме : и цифр, и поэтому подходит только к i: и i: еще есть, чтобы соответствовать.

person Wiktor Stribiżew    schedule 03.01.2018