c# – 以贪婪的重复方式回溯平衡组可能会导致失衡?

作为这个问题的一般酿造示例,我的意图是匹配一些数量的a,然后是相同数量的b,再加上一个b.

检查此代码段中显示的两种模式(also on 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,这是按预期的.

我可以解释这一点的唯一方法是,当(?< B-A> b)回溯以匹配少于b时,它从B堆栈弹出但不会推回从A堆栈相应弹出的内容.因此,即使现在由于回溯而少了一个b匹配,A堆栈仍然是空的.这是我能解释r1如何匹配aaabbb的唯一方法.

注意使用不情愿?在r2中不会导致此问题.我看待它的方式,这是因为不像贪婪的重复,不情愿的重复不必“消除”对A堆栈的损害,可以这么说.相比之下,贪婪的重复会导致尽可能多的“伤害”,但是回溯无法“将事物保持原样”到A堆栈.

这是对发生的事情的正确分析吗?如果是这样,这种行为是否符合设计?因为它对我来说基本上看起来像是在贪婪的重复中回溯平衡组可能会导致不平衡,因此这可能被归类为一个错误(或者至少是一个有点令人惊讶的行为,没有充分记录).

最佳答案 这是Mono的
bug.

人们在IdeOne上获得类似.NET的Environment.Version的原因是Mono要求向后兼容.NET,包括与基于框架版本做出决策的应用程序的兼容性.

点赞