0

OR条件を含む正規表現があります。「|」で区切られた正規表現に存在するすべての条件のうち、満たされた条件の数を見つけたいです。

例 :(.*Begin.*)|(.*Middle.*)|(.*End.*)

次のような文字列もあります。"Hello this is Begin.Hello this is Middle."

正規表現の 3 つの条件のうち 2 つが表示された場合、このルールでヒットします。ヒットした条件の数を見つけたい。

' ' に基づいて正規表現を分割し、|それぞれを個別に適用したくありません。正規表現全体を一度に実行したいのです。

サブマッチの順序は、検索している文字列内で常に Begin-->Middle-->End とは限りません。これは、1 つの正規表現に結合された条件を含む正規表現を適用する完全にランダムな文字列です。正規表現でこれらの条件がいくつヒットしたかを知りたいです。

4

4 に答える 4

2

要するに、これは標準の代替を使用することはできません。テキストが一致すると、再度一致することはありません。また、式が満たされると、検索を続行しません。正規表現が可能なすべての順列に一致しようとすると、非常に効率が悪く、誰も使用しません。

あなたの質問はドキュメントで明示的に対処されていませんが、私が見つけることができるのは、バックトラックのトピックでカバーされています。オプションの量指定子または代替コンストラクトを使用したMSDN の Backtracking を参照してください。

基本的に、代替リスト ( .|.|.) は後戻りの機会を生み出します。最初の代替が一致しない場合、2 番目が試行されます。ただし、最初の代替が失敗しない限り、このバックトラッキングは発生せず、一致が確立されると、他のすべての代替は無視されます。

複数の式に一致させたい場合は、次のように先読みを使用できます。

string l_pattern = @"(?i)" + /*make the regex case-insensitive*/
                   @"(?=(?<Cond1>.*?Begin)+)?" +
                   @"(?=(?<Cond2>.*?Middle)+)?" +
                   @"(?=(?<Cond3>.*?End)+)?";

string l_input = "Oops - I put the middle first!" + 
                 "Hello this is Begin.This is another begin.";

var l_match = Regex.Match( l_input, l_pattern );

Console.WriteLine( "Cond1 matched {0} times.",
                   l_match.Groups["Cond1"].Captures.Count );
Console.WriteLine( "Cond2 matched {0} times.",
                   l_match.Groups["Cond2"].Captures.Count );
Console.WriteLine( "Cond3 matched {0} times.",
                   l_match.Groups["Cond3"].Captures.Count );

Console.ReadKey( true );

これは出力されます:

Cond1 は 2 回一致します。
Cond2 は 1 回一致します。
Cond3 は 0 回一致します。

先読みはテキストをキャプチャしないため、正規表現内のミニ正規表現のように機能します。基本的に、この式は 3 つの式すべてを個別に実行するのと同じです。(各先読みはオプションであることに注意してください。そうしないと、先読みのいずれかが失敗すると、式全体が失敗します。)

また、先に示したように先読みを使用する場合、順序は重要ではないことに注意してください。

lookahed の詳細については、MSDN のZero-width positive lookahead assertionsを参照してください。このトピックは、SOの回答で完全に対処するには少し大きすぎます。

このアプローチを他のすべてのアプローチよりも推奨するとは言えません。正規表現に慣れていない場合、維持するのが難しい場合があり、必ずしも最も効率的なパターンではありませんが、指定された要件に適合します。

于 2013-05-22T17:12:27.670 に答える
0
Regex regexObj = new Regex("Begin|Middle|End");
allMatchResults = regexObj.Matches(subjectString);
numberOfMatches = allMatchResults.Count
于 2013-05-20T11:27:26.900 に答える
0

正規表現フラグメントが相互に排他的な言語のセットに一致する場合 (または、入力文字列内の重複しない部分文字列に一致するという、より弱いが検証が難しい条件)、すべての一致を見つけて、一致を構成するキャプチャ グループの数をカウントできます。文字列で。

正規表現フラグメントが重複する部分文字列と一致する場合、最も簡単な方法は、各正規表現フラグメントを文字列とカウントに対して照合することです。

于 2013-05-20T11:28:03.500 に答える