4

この質問の目的のために一般的に作成された例として、私の意図は、ある数aの 、次に同じ数bの 、さらにもう 1 つの に一致させることbです。

このスニペットに示されている 2 つのパターンを調べます (これも 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

2 つのパターンの一致には違いがあることに注意してください。r1は、バランシング グループ コンストラクトで貪欲な繰り返しを使用し、3aと 3に一致しますbが、これは意図したとおりではありませんr2しぶしぶ繰り返しを使用する は、2aと 3を与えますがb、これは意図したとおりです。

これを説明できる唯一の方法は、(?<B-A> b)+バックトラックが 1 つ少ない に一致する場合b、スタックからポップしBますが、対応してスタックからポップされたものをプッシュバックしないAということです。したがって、bバックトラッキングにより 1 つ少なく一致したとしても、Aスタックは空のままです。r1これは、どのように一致するかを説明できる唯一の方法ですaaabbb

reluctant +?inを使用しr2てもこの問題は発生しないことに注意してください。A私の見方では、貪欲な繰り返しとは異なり、消極的な繰り返しは、いわばスタックへの「ダメージを元に戻す」必要がないためです。対照的に、貪欲な繰り返しは可能な限り多くの「ダメージ」を引き起こしますが、バックトラックはAスタックに「物事をそのまま残す」ことに失敗します。

これは何が起こったのかについての正しい分析ですか?もしそうなら、これは仕様によるものですか? 基本的には、貪欲な繰り返しでバランシンググループを後戻りすると不均衡が生じる可能性があるため、これはバグとして分類される可能性があるためです (または、少なくとも文書化されていない驚くべき動作)。

4

1 に答える 1

2

これはMonoのバグです。

人々が IdeOne で .NET ライクになっている理由Environment.Versionは、フレームワークのバージョンに基づいて決定を下すアプリケーションとの互換性を含む、.NET との下位互換性の Mono 要件です。

于 2012-03-12T22:27:57.593 に答える