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/

5voto

Chad Scira Punkte 9375

Ich habe eine kleine JavaScript-Bibliothek geschrieben, die ausgeglichen um bei dieser Aufgabe zu helfen. Sie können dies erreichen, indem Sie

balanced.matches({
    source: source,
    open: '(',
    close: ')'
});

Sie können sogar einen Austausch vornehmen:

balanced.replacements({
    source: source,
    open: '(',
    close: ')',
    replace: function (source, head, tail) {
        return head + source + tail;
    }
});

Hier ist ein komplexeres und interaktives Beispiel JSFiddle .

5voto

Joy Hu Punkte 526

Der reguläre Ausdruck in Ruby (Version 1.9.3 oder höher):

/(?<match>\((?:\g<match>|[^()]++)*\))/

Demo auf rubular

2voto

Gene Olson Punkte 720
"""
Here is a simple python program showing how to use regular
expressions to write a paren-matching recursive parser.

This parser recognises items enclosed by parens, brackets,
braces and <> symbols, but is adaptable to any set of
open/close patterns.  This is where the re package greatly
assists in parsing. 
"""

import re

# The pattern below recognises a sequence consisting of:
#    1. Any characters not in the set of open/close strings.
#    2. One of the open/close strings.
#    3. The remainder of the string.
# 
# There is no reason the opening pattern can't be the
# same as the closing pattern, so quoted strings can
# be included.  However quotes are not ignored inside
# quotes.  More logic is needed for that....

pat = re.compile("""
    ( .*? )
    ( \( | \) | \[ | \] | \{ | \} | \< | \> |
                           \' | \" | BEGIN | END | $ )
    ( .* )
    """, re.X)

# The keys to the dictionary below are the opening strings,
# and the values are the corresponding closing strings.
# For example "(" is an opening string and ")" is its
# closing string.

matching = { "(" : ")",
             "[" : "]",
             "{" : "}",
             "<" : ">",
             '"' : '"',
             "'" : "'",
             "BEGIN" : "END" }

# The procedure below matches string s and returns a
# recursive list matching the nesting of the open/close
# patterns in s.

def matchnested(s, term=""):
    lst = []
    while True:
        m = pat.match(s)

        if m.group(1) != "":
            lst.append(m.group(1))

        if m.group(2) == term:
            return lst, m.group(3)

        if m.group(2) in matching:
            item, s = matchnested(m.group(3), matching[m.group(2)])
            lst.append(m.group(2))
            lst.append(item)
            lst.append(matching[m.group(2)])
        else:
            raise ValueError("After <<%s %s>> expected %s not %s" %
                             (lst, s, term, m.group(2)))

# Unit test.

if __name__ == "__main__":
    for s in ("simple string",
              """ "double quote" """,
              """ 'single quote' """,
              "one'two'three'four'five'six'seven",
              "one(two(three(four)five)six)seven",
              "one(two(three)four)five(six(seven)eight)nine",
              "one(two)three[four]five{six}seven<eight>nine",
              "one(two[three{four<five>six}seven]eight)nine",
              "oneBEGINtwo(threeBEGINfourENDfive)sixENDseven",
              "ERROR testing ((( mismatched ))] parens"):
        print "\ninput", s
        try:
            lst, s = matchnested(s)
            print "output", lst
        except ValueError as e:
            print str(e)
    print "done"

1voto

Shell Scott Punkte 1389

Sie brauchen die erste und die letzte Klammer. Verwenden Sie etwas wie dieses:

str.indexOf('('); - ergibt das erste Vorkommen

str.lastIndexOf(')'); - letzter

Sie brauchen also einen String dazwischen,

String searchedString = str.substring(str1.indexOf('('),str1.lastIndexOf(')');

1voto

Douglas Leeder Punkte 50423

Die Antwort hängt davon ab, ob Sie übereinstimmende Sätze von Klammern oder nur die erste offene bis zur letzten geschlossenen Klammer im Eingabetext abgleichen müssen.

Wenn Sie übereinstimmende verschachtelte Klammern abgleichen müssen, dann brauchen Sie etwas anderes als reguläre Ausdrücke. - siehe @dehmann

Wenn es sich nur um das erste Öffnen bis zum letzten Schließen handelt, siehe @Zach

Entscheiden Sie, was mit Ihnen geschehen soll:

abc ( 123 ( foobar ) def ) xyz ) ghij

Sie müssen entscheiden, wie Ihr Code in diesem Fall aussehen soll.

4 Stimmen

Dies ist keine Antwort.

0 Stimmen

Ja, die Forderung nach einer Änderung der Fragestellung sollte als Kommentar angegeben werden,

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