431 Stimmen

Regulärer Ausdruck für die Übereinstimmung von ausgeglichenen Klammern

Ich brauche einen regulären Ausdruck, um den gesamten Text zwischen zwei äußeren Klammern auszuwählen.

Exemple :
START_TEXT(text here(possible text)text(possible text(more text)))END_TXT
^ ^

Ergebnis:
(text here(possible text)text(possible text(more text)))

7 Stimmen

Diese Frage ist sehr schlecht, weil nicht klar ist, worum es geht. Alle Antworten haben sie unterschiedlich interpretiert. @DaveF können Sie bitte die Frage klären?

2 Stimmen

In diesem Beitrag wird geantwortet: stackoverflow.com/questions/6331065/

26voto

Tomalak Punkte 320467
(?<=\().*(?=\))

Wenn Sie Text zwischen zwei Zeilen auswählen möchten passend zu Klammern, haben Sie mit regulären Ausdrücken kein Glück. Das ist unmöglich (*) .

Diese Regex gibt nur den Text zwischen der ersten öffnenden und der letzten schließenden Klammer in Ihrer Zeichenkette zurück.


(*) Es sei denn, Ihre Regex-Engine hat Funktionen wie Bilanzkreise o Rekursion . Die Zahl der Motoren, die solche Funktionen unterstützen, wächst langsam, aber sie sind immer noch nicht allgemein verfügbar.

0 Stimmen

Was bedeuten die Zeichen "<=" und "="? Auf welche Regexp-Engine zielt dieser Ausdruck ab?

2 Stimmen

Dabei handelt es sich um "Look-Around" oder besser gesagt um "Zero Width Look-Ahead/Look-Behind Assertions". Die meisten modernen Regex-Engines unterstützen sie.

0 Stimmen

Gemäß dem Beispiel des Auftraggebers möchte er die äußersten Parens in die Übereinstimmung einbeziehen. Diese Regex verwirft sie.

14voto

Alexander Bartosh Punkte 7681

Es ist tatsächlich möglich, dies mit regulären Ausdrücken in .NET zu tun, aber es ist nicht trivial, also lesen Sie sorgfältig.

Sie können einen schönen Artikel lesen aquí . Möglicherweise müssen Sie sich auch über reguläre Ausdrücke in .NET informieren. Sie können mit der Lektüre von aquí .

Eckige Klammern <> wurden verwendet, weil sie kein Escaping erfordern.

Der reguläre Ausdruck sieht wie folgt aus:

<
[^<>]*
(
    (
        (?<Open><)
        [^<>]*
    )+
    (
        (?<Close-Open>>)
        [^<>]*
    )+
)*
(?(Open)(?!))
>

12voto

Manish Punkte 3145

Ich war auch in dieser Situation, wo verschachtelte Muster kommt stecken.

Reguläre Ausdrücke sind das Richtige, um das oben genannte Problem zu lösen. Verwenden Sie folgendes Muster

'/(\((?>[^()]+|(?1))*\))/'

2 Stimmen

Als Benutzer, der nach Hilfe zu einem ähnlichen Thema sucht, habe ich keine Ahnung, was diese Regex genau tut und wie ich sie auf mein eigenes Problem anwenden kann. Vielleicht ist dies eine gute Antwort, aber da Regex von Natur aus kryptisch sind, müsste ich jeden Teil davon nachschlagen, um zu sehen, ob mir das helfen würde. Angesichts der Tatsache, dass es so viele Antworten mit dieser Art von "Lösung" gibt, glaube ich nicht, dass ich das tun werde.

1 Stimmen

regex101.com ist ein gutes Erklärungsinstrument, um diese Regex zu erläutern.

0 Stimmen

Diese PCRE-Lösung mit ?1 funktioniert mit (*SKIP)(*FAIL), wenn die ?R-Methode, die von Wackelpudding nicht. Verwenden Sie diese Lösung, wenn Sie Dinge finden müssen, die SIND NICHT in Klammern. Ich habe hier ein Beispiel erstellt: regex101.com/r/xkVzVP/1

6voto

Marco Punkte 328

Dies ist die endgültige Regex:

\(
(?<arguments> 
(  
  ([^\(\)']*) |  
  (\([^\(\)']*\)) |
  '(.*?)'

)*
)
\)

Exemple :

input: ( arg1, arg2, arg3, (arg4), '(pip' )

output: arg1, arg2, arg3, (arg4), '(pip'

beachten Sie, dass die '(pip' wird korrekt als String verwaltet. (ausprobiert in regulator: http://sourceforge.net/projects/regulator/ )

0 Stimmen

Ich mag diese Technik, wenn es keine Verschachtelung gibt oder Sie sich nur für die innerste Gruppe interessieren. Sie beruht nicht auf einer Rekursion. Ich konnte damit ein Argument extrahieren, das Klammern enthielt. Ich habe ein funktionierendes Beispiel unter Regex101

5voto

Wiktor Stribiżew Punkte 551798

Hinzufügen zu Wackelpudding's Antwort gibt es andere Regex-Varianten, die rekursive Konstrukte unterstützen.

Lua

Utilice %b() ( %b{} / %b[] für geschweifte Klammern / eckige Klammern):

  • for s in string.gmatch("Extract (a(b)c) and ((d)f(g))", "%b()") do print(s) end (siehe Demo )

Raku (früher Perl6) :

Nicht überschneidende Übereinstimmungen mit mehreren ausgeglichenen Klammern:

my regex paren_any { '(' ~ ')' [ <-[()]>+ || <&paren_any> ]* }
say "Extract (a(b)c) and ((d)f(g))" ~~ m:g/<&paren_any>/;
# => ((a(b)c) ((d)f(g)))

Überschneidungen mit mehreren ausgeglichenen Klammern:

say "Extract (a(b)c) and ((d)f(g))" ~~ m:ov:g/<&paren_any>/;
# => ((a(b)c) (b) ((d)f(g)) (d) (g))

Ver Demo .

Python re Nicht-Regex-Lösung

Ver Antwort von Stochern para Wie man einen Ausdruck zwischen ausgeglichenen Klammern erhält .

Mit Java anpassbare Nicht-Regex-Lösung

Hier ist eine anpassbare Lösung, die es erlaubt, einzelne Zeichen als Begrenzungszeichen in Java zu verwenden:

public static List<String> getBalancedSubstrings(String s, Character markStart, 
                                 Character markEnd, Boolean includeMarkers) 

{
        List<String> subTreeList = new ArrayList<String>();
        int level = 0;
        int lastOpenDelimiter = -1;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == markStart) {
                level++;
                if (level == 1) {
                    lastOpenDelimiter = (includeMarkers ? i : i + 1);
                }
            }
            else if (c == markEnd) {
                if (level == 1) {
                    subTreeList.add(s.substring(lastOpenDelimiter, (includeMarkers ? i + 1 : i)));
                }
                if (level > 0) level--;
            }
        }
        return subTreeList;
    }
}

Beispielhafte Verwendung:

String s = "some text(text here(possible text)text(possible text(more text)))end text";
List<String> balanced = getBalancedSubstrings(s, '(', ')', true);
System.out.println("Balanced substrings:\n" + balanced);
// => [(text here(possible text)text(possible text(more text)))]

0 Stimmen

Siehe eine Online-Java-Demo für einen Beweis, dass es mit mehreren Übereinstimmungen funktioniert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X