it-swarm.com.de

Gierige, nicht gierige, allgierige Übereinstimmung in C # Regex

Wie bekomme ich alle Übereinstimmungen im folgenden Beispiel:

// 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"

P .: Ich möchte, dass alle Übereinstimmungen generisch sind. Das obige Beispiel ist nur ein Beispiel.

21
Peter Lee

Sie könnten so etwas verwenden:

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

Dann sollten Sie drei Rückreferenzen mit ab, abc und abcd haben.

Aber ehrlich gesagt macht diese Art von Regex nicht viel Sinn, besonders wenn sie größer wird, wird sie unlesbar.

Bearbeiten:

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

Und Sie haben dort übrigens einen Fehler bekommen. Dies kann nur ab und abc entsprechen (lesen: ab + beliebiges (optionales) Zeichen)

Faule Version von:

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

ist:

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

Wenn eine Lösung vorhanden ist, umfasst dies wahrscheinlich eine Erfassungsgruppe und die Option RightToLeft:

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

ausgabe:

abcd
abc
ab

Ich sage "wenn", denn obwohl es für Ihren einfachen Testfall funktioniert, kann ich nicht garantieren, dass dieser Trick bei Ihrem realen Problem hilfreich ist. Der RightToLeft-Modus ist eine der innovativsten Funktionen von .NET. Ich kann mir keine andere Variante vorstellen, die etwas Äquivalentes hat. Die offizielle Dokumentation dazu ist spärlich (um es milde auszudrücken), und bisher scheint es nicht viele Entwickler zu geben, die es verwenden und ihre Erfahrungen online teilen. Also probieren Sie es aus und sehen Sie, was passiert.

4
Alan Moore

Sie können nicht drei verschiedene Ergebnisse von nur einem Spiel erhalten.

Wenn Sie nur "ab" zuordnen möchten, können Sie ab.? oder a.{1} (oder viele andere Optionen) verwenden.
Wenn Sie nur "abc" abgleichen möchten, können Sie ab. oder a.{2} (oder viele andere Optionen) verwenden.
Wenn Sie nur "abcd" abgleichen möchten, können Sie ab.* oder a.{3} (oder viele andere Optionen) verwenden.

1
Colin Hebert