2012-06-15 12 views
7

Ich habe eine Reihe von gruppierten Werten, die einem bestimmten Format folgen und einen einzelnen Ausdruck verwenden möchten, um sie in Gruppen zu erfassen. Zum Beispiel habe ich -group1 -group2 -group3 und versuche etwas ähnliches zu verwenden (-[\s\S]{1,}?) Dies ist im Grunde erlaubt es mir, die gesamte Zeichenfolge in einer einzigen Gruppe zu erfassen, aber ich möchte in der Lage sein, jeden der Werte separat zu reference. Ich dachte, die ? würde es zwingen, nicht gierig zu sein und deshalb die Musterübereinstimmung in drei verschiedene Gruppen aufteilen (zum Beispiel). Für jetzt wiederhole ich einfach die Referenz (-[\s\S]*?), aber es scheint, dass es einen eleganteren Ausdruck geben sollte.
Danke!Regulärer Ausdruck zum Auswählen von Wiederholungsgruppen

+0

Dies ist etwas vage. Können Sie Beispieltext und das erwartete Gruppierungsergebnis einschließlich der beabsichtigten Rückreferenz anzeigen? –

+0

Übrigens, '[\ s \ S]' sagt "Entspricht irgendeinem Leerzeichen oder Nicht-Leerzeichen". Denk darüber nach. ;) – qJake

Antwort

14

Sie im Glück, weil C# eine der wenigen Sprachen (wenn nicht die einzige), die subexpression

fängt unterstützt ist

https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.capture(v=vs.110)

können .NET API betrachtet werden als

Matches 
    Groups (most regex engines stop here) 
     Captures (unique for .NET) 
folgt

Es ist nicht klar aus Ihrer Frage, was Sie genau übereinstimmen möchten, aber das sollte Ihnen den Anfang machen. Frage noch einmal, ob du feststeckst.

string input = "-group1 -group2 "; 
    string pattern = @"(-\S*\W){2}"; 
    foreach (Match match in Regex.Matches(input, pattern)) 
    { 
    Console.WriteLine("Match: {0}", match.Value); 
    for (int groupCtr = 0; groupCtr < match.Groups.Count; groupCtr++) 
    { 
     Group group = match.Groups[groupCtr]; 
     Console.WriteLine(" Group {0}: {1}", groupCtr, group.Value); 
     for (int captureCtr = 0; captureCtr < group.Captures.Count; captureCtr++) 
      Console.WriteLine("  Capture {0}: {1}", captureCtr, 
          group.Captures[captureCtr].Value); 
    }      
    } 

Diese ouputs

Match: -group1 -group2 
    Group 0: -group1 -group2 
     Capture 0: -group1 -group2 
    Group 1: -group2 
     Capture 0: -group1 
     Capture 1: -group2 

Wie Sie (Gruppe 1, Capture-0) und (Gruppe 1 Capture 1) bieten die einzelnen Aufnahmen einer Gruppe (und nicht zuletzt, wie in den meisten sehen Sprachen)

die Adresse ich denke, was Sie beschreiben, wie „jeder der Werte der Lage sein, Rückreferenzierung separat“

(Sie den Begriff Rückreferenzierung benutzen, aber ich glaube nicht, Sie ar streben Platzierungsmuster rechts?)

+1

+1. Ich glaube, das ist es, wonach er auch gefragt hat. Nebenbei bietet PHP dies mit seinem '' preg_match_all (...) '' Funktion; Mit dem '' PREG_SET_ORDER''-Flag gibt es ein mehrdimensionales Array zurück, das erste Array enthält den ersten Satz, das zweite Array enthält den zweiten Satz usw. (Andere Flags erlauben unterschiedliche Darstellungen.) Meine Vermutung ist, wenn .NET und PHP haben es implementiert, andere Sprachen haben es auch. –

+0

@ acheong87 Guter Kommentar, ich werde es der Antwort hinzufügen, um andere Sprachen nicht zu beleidigen :) Ich habe es von dem Regexp-Experten Jan Goyvaerts, dass .NET in diesem Aspekt einzigartig war, aber ich bin nicht aktiv genug auf anderen Plattformen, um dies zu unterstützen oben. – buckley

+2

@ acheong87, das ist nicht das Gleiche. 'preg_match_all()' wendet die Regex wiederholt an und gibt die gesammelten Ergebnisse zurück, ähnlich wie die 'Matches()' Methode von .NET. Das OP möchte * eine * Übereinstimmung ausführen, die den gesamten String konsumiert, und dann die einzelnen Captures ausbrechen. .NET stellt zu diesem Zweck die 'CaptureCollection' bereit, aber PHP hat keine Entsprechung. –

0

Versuchen Sie folgendes:

(-.+?)(\s|$) 

Ihre erste Capture-Gruppe haben, was Sie wollen (-group1, -group2, etc).

Wenn Sie mehr Kontrolle darüber haben möchten, was nach dem - zulässig ist, ändern Sie .+? in beispielsweise [a-zA-Z0-9]+? so, dass nur alphanumerische Zeichen übereinstimmen.

2

Mit .NET Regex (und fast nur .NET) können Sie:

(?:(-\S+)\s*)+ 

Gruppe 1 wird eine Liste aller angepassten Zeichenketten enthalten.

Oder vielleicht nur Matches verwendet, ist in Ihrem Fall ausreichend:

var re = new Regex(@"-\S+"); 
var matches = re.Matches(str); 
Verwandte Themen