В качестве общего примера для данного вопроса я собираюсь сопоставить некоторое число a
, затем равное число b
плюс еще один b
.
Изучите два шаблона, представленные в этом фрагменте ( также на ideone.com ):
var r1 = new Regex(@"(?xn)
(?<A> a)+ (?<B-A> b)+ (?(A)(?!)) b
");
var r2 = new Regex(@"(?xn)
(?<A> a)+ (?<B-A> b)+? (?(A)(?!)) b
");
Console.WriteLine(r1.Match("aaabbb"));
// aaabbb
Console.WriteLine(r2.Match("aaabbb"));
// aabbb
Обратите внимание, что между двумя шаблонами есть различия,r1
, который использует жадное повторение в конструкции балансировочной группы, соответствует 3 a
и 3 b
, что соответствует НЕ , как предполагалось.r2
, который использует неохотное повторение, дает мне 2 a
и 3 b
, что IS , как и предполагалось.
Единственный способ объяснить этов том, что когда (?<B-A> b)+
возвращается назад, чтобы соответствовать одному меньше b
, оно появляется из стека B
, но НЕ возвращает то, что было соответственно извлечено из стека A
.Таким образом, несмотря на то, что из-за обратного отслеживания теперь сопоставляется на единицу меньше b
, стек A
остается пустым.Это единственный способ, которым я могу объяснить, как r1
может соответствовать aaabbb
.
Обратите внимание, что использование неактивного +?
в r2
не вызывает этой проблемы.На мой взгляд, это потому, что в отличие от жадного повторения, неохотное повторение не должно, так сказать, «устранять ущерб» стеку A
.Напротив, жадное повторение наносит как можно больше «ущерба», но при возврате не удается «оставить все как есть» в стеке A
.
Является ли это правильным анализом того, что произошло?И если так, это поведение по замыслу?Потому что для меня это в основном похоже на то, что возвращение балансирующей группы в жадном повторении может привести к дисбалансу, и, таким образом, это может быть отнесено к категории ошибок (или, по крайней мере, несколько удивительное поведение, которое недостаточно документировано).