2010-10-09 8 views
19

Wie kann ich alle Spiele im folgenden Beispiel erhalten:Greedy, Nicht Greedy, All-Greedy Matching in C# Regex

// 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. S .: Ich möchte die alle Spiele in einer allgemeinen Weise haben. Das obige Beispiel ist nur ein Beispiel.

+1

Was ist Ihr Anwendungsfall? Wir können Ihnen mit ein bisschen mehr Information einen besseren Rat geben. Gerade jetzt, diese Aufgabe sieht sehr bizarr und vielleicht schlecht beraten. – user359996

+0

Hallo user359996, danke für Ihre Kommentare. Ich stimme dem zu, was Sie erwähnt haben. Ich werde meinen Kunden kontaktieren, um zu sehen, ob dies notwendig ist oder nicht. –

Antwort

17

Sie so etwas wie verwenden:

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

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

Aber um ehrlich zu sein, diese Art von Regex macht nicht viel Sinn, vor allem wenn es größer wird es unlesbar wird.

Edit:

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

Und einen Fehler bekommen es btw. Dies kann nur passen ab und abc (sprich: ab + any (optional) Zeichen

Faule Version:

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

ist:

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

Hallo Tseng, ich stimme zu, dass diese RegEx seltsam aussieht, ich werde meinen Kunden kontaktieren, um zu überprüfen, ob sie es wirklich brauchen. –

+0

Ich diskutierte mit meinem Kunden, und sie sagten, das ist nicht notwendig. Danke für deine Antwort. –

1

Sie können nicht drei verschiedene Ergebnisse von nur einer Übereinstimmung erhalten.

Wenn Sie nur „ab“ passen Sie ab.? oder a.{1} (oder viele andere Optionen) verwenden können
Wenn Sie nur „abc“ passen Sie ab. oder a.{2} (oder viele andere nutzen können Optionen)
Wenn Sie nur „ABCD“ Sie ab.* oder a.{3} (oder viele andere Optionen verwenden können, passen wollen)

+0

Hallo Tahbaza und Colin Hebert, danke für deine Antwort. aber ich frage mich, ob es einen generischen Weg gibt, nicht nur für dieses spezielle Beispiel. –

4

Wenn eine Lösung existiert, es geht wahrscheinlich ein Erfassung Gruppe und die RightToLeft Option:

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" weil, während es für Ihren einfachen Testfall funktioniert, kann ich nicht garantieren, dass dieser Trick mit Ihrem realen Problem helfen wird. RightToLeft Modus ist eine der innovativsten Funktionen von .NET - ohne weiteres, ich kann mir keinen anderen Geschmack vorstellen, der etwas Ähnliches hat. Die offizielle Dokumentation darüber ist spärlich (um es milde auszudrücken), und bisher scheint es nicht viele Entwickler, die es benutzen und ihre Erfahrungen online teilen. Probieren Sie es aus und sehen Sie, was passiert.