Ruby - Regex für passende Klammern?

8

Ich versuche herauszufinden, ob eine Zeichenfolge richtig Klammern geschlossen hat.

Um dies zu tun, verwende ich die folgenden drei Klammerpaare.

%Vor%

Die Klammern können auch verschachtelt sein, solange sie richtig formatiert sind.

%Vor%

Ich habe versucht, Regex zu verwenden, und nach ein bisschen herumfummeln, habe ich das.

%Vor%

Allerdings gibt es ein paar Probleme damit.

Es passt nur zu Klammern, aber nicht mit Klammern

Ich verstehe nicht, warum es nicht mit den Klammern übereinstimmt.

In meinen Beispielen habe ich eindeutig einen Backslash vor den Klammern verwendet.

Eingabe

%Vor%     
Johnson 22.09.2014, 17:00
quelle

8 Antworten

9
%Vor%     
sawa 22.09.2014, 17:45
quelle
5

Laut diesem Artikel unterstützt Ruby ab Version 2.0 rekursive Regexps. Dies bedeutet, dass Sie das Ruby-spezifische Token \g<0> verwenden können, um rekursiv die gesamte regexp-Datei an jedem beliebigen Punkt Ihrer regulären Ausgabe abzugleichen. Dieser Ansatz kann Stack effektiv emulieren, um Ihre Aufgabe zu lösen.

Hier ist die resultierende regexp: %Code%

Diese aktualisierte Version behandelt Fälle wie folgt: [^(){}\[\]]*(\((\g<0>)?\)|\{(\g<0>)?\}|\[(\g<0>)?\])?[^(){}\[\]]* , wenn mehrere Klammergruppen auf derselben Ebene sind. Danke @Jonny 5 für den Hinweis auf diesen Fall:

%Vor%

Dieser Ausdruck erfordert die Überprüfung, ob die gesamte Eingabezeichenfolge übereinstimmt. Teilweise Übereinstimmung bedeutet, dass in Klammern ein Fehler in der Reihenfolge der Zeichenfolge auftritt.

Hier ist eine andere Version, die nicht überprüfen muss, ob die gesamte Eingabezeichenfolge übereinstimmt:

%Vor%

Sie werden möglicherweise feststellen, dass es versucht, das entsprechende Klammerpaar zu finden, und dann rekursiv mit sich selbst übereinstimmt. Ich habe es hier ausprobiert und es scheint zu funktionieren. Ich bin kein Ruby-Ingenieur, also kann ich keinen Ruby-Test durchführen, hoffe aber, dass es nicht nötig ist.

    
Aivean 22.09.2014 18:14
quelle
5

Dies ist wahrscheinlich ein schlechter Anwendungsfall für eine Regex, ich würde einen einfachen Stapelparser verwenden.

%Vor%

edit: Cary Swoveland - schreiben Sie tatsächlichen Code und haben Leute kritisieren: - ?.

updated: Hatte einen kleinen Fehler darin, dass ich überprüft habe, ob das schließende Zeichen mit dem ersten übereinstimmt. repariere es!

    
Jeff Price 22.09.2014 17:13
quelle
2

Ich nehme an, Ihre Zeichenfolge besteht nur aus den Zeichen in der Zeichenfolge "()[]{}" . Beachten Sie, dass für eine Zeichenfolge str die Übereinstimmungsanforderung erfüllt ist:

  • str muss leer sein oder einen Teilstring enthalten "()" , "[]" oder "[]" ; und
  • Wenn str nicht leer ist, erfüllt str mit "()" , "[]" und "[]" entfernt die Matching-Anforderung.

Wir können daher Teilstringpaare nacheinander entfernen, bis wir es nicht mehr tun können. Wenn das, was übrig ist, leer ist, erfüllt die ursprüngliche Zeichenfolge die Übereinstimmungsanforderung; Sonst nicht:

%Vor%     
Cary Swoveland 22.09.2014 17:42
quelle
2

Regex ist nicht dafür gedacht, korrekte Grammatik in Strings zu validieren und dafür sehr schlecht geeignet. Regex ist ein Werkzeug, um Muster im Text zu finden.

Sie sollten einen Parser verwenden.

Hier ist Ruby-Code für einen Stapel-Parser:

%Vor%     
dfherr 22.09.2014 17:07
quelle
2

Bearbeiten: nach Jonny 5's Vorschlag verschoben Nach dem Lesen der Kommentare unten und inspiriert von Aiveans Lösung, hier ist ein modifiziertes Muster von (\[([^][)({}]|\g<0>)*\])|\(\g<2>*\)|\{\g<2>*\}


Wenn Ihre Regex-Engine Rekursion unterstützt, schlage ich vor, 3 verschiedene Muster als Filter zu verwenden. Wenn Ihre Eingaben alle drei passieren, ist es eine gute Übereinstimmung -

([(?:[^][]|(?R))]) # match nested [] 
(((?:[^)(]|(?R)))) # match nested ()
({(?:[^{}]|(?R))*}) # match nested {}

    
alpha bravo 22.09.2014 17:50
quelle
2

Okay, ich habe das herausgefunden.

%Vor%     
Johnson 23.09.2014 22:21
quelle
1

Ich sehe nicht, wie Sie erwarten können, dass Ihre Regex mit Klammern übereinstimmt. Hier ist was deine Regex tut:

%Vor%     
Tim Pietzcker 22.09.2014 17:07
quelle

Tags und Links