it-swarm.com.de

C # Regex.Match geschweifte Klammern - nur Inhalt? (Klammern ausschließen)

Ich habe keine Antwort darauf gefunden: Kann ich die Regex.Matches-Methode verwenden, um nur den Inhalt von Elementen mit geschweiften Klammern zurückzugeben?

Wenn ich den Regex ({[^}]*}) verwende, werden die geschweiften Klammern in meine MatchCollection-Werte aufgenommen. Ich möchte übereinstimmen, aber dann nur den Inhalt zurückgeben. Folgendes habe ich bisher:

Regex regex = new Regex(({[^}]*}), RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches("Test {Token1} {Token 2}");
// Results include braces (undesirable)
var results = matches.Cast<Match>().Select(m => m.Value).Distinct().ToList();
18
PeterX

Mir hat es immer explizit gefallen. Sie können also die Gruppen "positives Aussehen" (? <= ...) und "positives Aussehen" (? = ...) verwenden:

(?<=\{)
[^}]*
(?=\})

was bedeutet:

  • Öffnen der geschweiften Klammer vor Übereinstimmung
  • sammle Text (von natürlich) - wie bereits erwähnt, kann ich auch [^ {}] * sein
  • geschlossene geschweifte Klammer nach Übereinstimmung erfordern
24

Wie in vielen anderen Programmiersprachen unterstützt die Regex-Engine in C #Erfassungsgruppen, dh Submatches, Teile von Teilzeichenfolgen, die einem ganz bestimmten Regex-Muster entsprechen in einem Regex-Muster mit Hilfe von Klammern (z. B. wird 1([0-9])3 mit 123 übereinstimmen und den Wert von 2 in einem Puffer der Erfassungsgruppe 1 speichern). Auf erfasste Texte kann über Match.Groups[n].Value zugegriffen werden, wobei n der Index der Erfassungsgruppe innerhalb des Musters ist.

Capturing ist viel effektiver als Lookarounds . Wenn keine komplexen Bedingungen erforderlich sind, sind die Erfassung von Gruppen wesentlich bessere Alternativen.

Sehen Sie meinen Regex-Geschwindigkeitstest, der auf regexhero.net durchgeführt wird:

 enter image description here

Nun, wie können wir den Teilstring in geschweiften Klammern erhalten?

  • wenn sich keine weiteren geschweiften Klammern im Inneren befinden, mit einer negierten Zeichenklasse: {([^{}]*)
  • wenn geschachtelte geschweifte Klammern vorhanden sein können: {((?>[^{}]+|{(?<c>)|}(?<-c>))*(?(c)(?!)))

In beiden Fällen stimmen wir mit einem Anfangscode { überein und passen dann (1) jedes andere Zeichen als { oder } oder (2) alle Zeichen bis zum ersten gepaarten } an.

Hier ist Beispielcode :

var matches = Regex.Matches("Test {Token1} {Token 2}", @"{([^{}]*)");
var results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct().ToList();
Console.WriteLine(String.Join(", ", results));
matches = Regex.Matches("Test {Token1} {Token {2}}", @"{((?>[^{}]+|{(?<c>)|}(?<-c>))*(?(c)(?!)))");
results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct().ToList();
Console.WriteLine(String.Join(", ", results));

Ergebnis: Token1, Token 2, Token1, Token {2}.

Beachten Sie, dass RegexOptions.IgnoreCase überflüssig ist, wenn Sie keine Buchstaben haben, die unterschiedliche Muster im Muster haben können.

11

Danke Milosz Krajewski, nichts hinzuzufügen, aber hier ist die Funktion

private List<String> GetTokens(String str)
{
    Regex regex = new Regex(@"(?<=\{)[^}]*(?=\})", RegexOptions.IgnoreCase);
    MatchCollection matches = regex.Matches(str);

    // Results include braces (undesirable)
    return matches.Cast<Match>().Select(m => m.Value).Distinct().ToList();
}
5
bunjeeb

Bewegen Sie die Klammern einfach außerhalb der Klammern:

 {([^}]*)}
3
RichieHindle

Es ist Regex für C # .net.

@"{(.*?)}"

es zeigt a

token1 token2

2

Wenn ich verstehe, was du willst. Ändern Sie die Regex in {([^}]*)}. Dadurch wird nur der Text zwischen {} erfasst und nicht eingeschlossen.

0
UberMouse

Ein wenig die Antwort von @Milosz Krajewski modifizieren

(?<=\{)[^}{]*(?=\})

dadurch werden die mittleren einzelnen öffnenden und schließenden geschweiften Klammern im String übersprungen.

0
sumit sharma