24

次の例ですべての一致を取得するにはどうすればよいですか。

// Only "abcd" is matched
MatchCollection greedyMatches = Regex.Matches("abcd", @"ab.*");

// Only "ab" is matched
MatchCollection lazyMatches   = Regex.Matches("abcd", @"ab.*?");

// How can I get all matches: "ab", "abc", "abcd"

PS:すべての一致を一般的な方法で行いたいです。上記の例はほんの一例です。

4

3 に答える 3

23

次のようなものを使用できます。

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"(((ab)c)d)");

次に、ab、abc、および abcd による 3 つの後方参照が必要です。

しかし、正直なところ、この種の正規表現はあまり意味がありません。特に、大きくなると判読できなくなります。

編集:

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"ab.?");

そして、ところでエラーが発生しました。これは ab と abc にのみ一致します (読み取り: ab + 任意の (オプション) 文字)

以下の遅延バージョン:

MatchCollection greedyMatches    = Regex.Matches("abcd", @"ab.*");

は:

MatchCollection nonGreedyMatches    = Regex.Matches("abcd", @"ab.*?");
于 2010-10-09T23:06:00.807 に答える
6

解決策が存在する場合、おそらくキャプチャ グループと RightToLeft オプションが含まれます。

string s = @"abcd";
Regex r = new Regex(@"(?<=^(ab.*)).*?", RegexOptions.RightToLeft);
foreach (Match m in r.Matches(s))
{
  Console.WriteLine(m.Groups[1].Value);
}

出力:

abcd
abc
ab

「もし」と言ったのは、単純なテスト ケースでは機能しますが、このトリックが実際の問題に役立つとは限らないためです。 RightToLeftモードは .NET のより革新的な機能の 1 つです。それに関する公式ドキュメントはまばらで (控えめに言っても)、これまでのところ、それを使用して経験をオンラインで共有している開発者は多くないようです。試してみて、何が起こるか見てみましょう。

于 2010-10-10T01:05:33.170 に答える
1

たった 1 つの試合で 3 つの異なる結果を得ることはできません。

「ab」のみに一致させたい場合は、ab.?or a.{1}(または他の多くのオプション)
を使用できます。「abc」のみに一致させたい場合は、 ab.or (または他の多くa.{2}のオプション) を使用できます
。「abcd」のみに一致させたい場合"ab.*またはa.{3}(または他の多くのオプション)を使用できます

于 2010-10-09T22:50:20.660 に答える