Oto rozwiązanie pyparsing który wykorzystuje samodzielne modyfikowanie gramatyki dynamicznie dopasować właściwy znak zamykający nawias.
from pyparsing import *
data = '(gimme [some {nested, nested [lists]}])'
opening = oneOf("({ [")
nonBracePrintables = ''.join(c for c in printables if c not in '(){}[]')
closingFor = dict(zip("({[",")}]"))
closing = Forward()
# initialize closing with an expression
closing << NoMatch()
closingStack = []
def pushClosing(t):
closingStack.append(closing.expr)
closing << Literal(closingFor[t[0]])
def popClosing():
closing << closingStack.pop()
opening.setParseAction(pushClosing)
closing.setParseAction(popClosing)
matchedNesting = nestedExpr(opening, closing, Word(alphas) | Word(nonBracePrintables))
print matchedNesting.parseString(data).asList()
drukuje:
[['gimme', ['some', ['nested', ',', 'nested', ['lists']]]]]
aktualizacja: napisałem wyżej rozwiązanie, bo rzeczywiście napisany go ponad rok temu jako eksperyment. Po prostu przyjrzałem się bliżej oryginalnemu wpisowi i przypomniałem sobie definicję typu rekursywnego utworzoną za pomocą metody operatorPrecedence
, a więc zmieniłem to rozwiązanie, używając oryginalnego podejścia - o wiele prostszego do naśladowania! (Może mieć problem od lewej rekursji z prawej danych wejściowych choć nie dokładnie testowane):
from pyparsing import *
enclosed = Forward()
nestedParens = nestedExpr('(', ')', content=enclosed)
nestedBrackets = nestedExpr('[', ']', content=enclosed)
nestedCurlies = nestedExpr('{', '}', content=enclosed)
enclosed << (Word(alphas) | ',' | nestedParens | nestedBrackets | nestedCurlies)
data = '(gimme [some {nested, nested [lists]}])'
print enclosed.parseString(data).asList()
Daje:
[['gimme', ['some', ['nested', ',', 'nested', ['lists']]]]]
Paul, dziękuję bardzo za odpowiedź informacyjną. I jeszcze więcej dziękuję za tworzenie i otwieranie mojej nowej ulubionej biblioteki Pythona! pyparsing pomaga mi radykalnie zmniejszyć rozmiar, złożoność i łatwość obsługi projektu, nad którym pracuję. – Derek
Dzięki za komplementy, witamy w pyparstwie! – PaulMcG