14

pyparsing を使用して、フォームの式を解析し、フォームexpr = '(gimme [some {nested [lists]}])'の python リストを取得したいと思います: [[['gimme', ['some', ['nested', ['lists']]]]]]。現在、私の文法は次のようになっています。

nestedParens = nestedExpr('(', ')')
nestedBrackets = nestedExpr('[', ']')
nestedCurlies = nestedExpr('{', '}')
囲まれた = nestedParens | ネストされたブラケット | ネストされたカーリー

現在、 enclosed.searchString(expr)次の形式のリストを返します[[['gimme', ['some', '{nested', '[lists]}']]]]。角括弧または中括弧を認識していないため、これは私が望むものではありませんが、その理由はわかりません。

4

2 に答える 2

27

これは、自己変更文法を使用して正しい右中括弧文字を動的に照合する pyparsing ソリューションです。

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()

プリント:

[['gimme', ['some', ['nested', ',', 'nested', ['lists']]]]]

更新:上記のソリューションを投稿したのは、実際には 1 年以上前に実験として書いたからです。元の投稿を詳しく調べたところ、メソッドによって作成された再帰型定義について考えさせられたoperatorPrecedenceので、元のアプローチを使用してこのソリューションをやり直しました-従うのがはるかに簡単です! (ただし、十分にテストされていないため、右の入力データに左再帰の問題がある可能性があります):

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()

与えます:

[['gimme', ['some', ['nested', ',', 'nested', ['lists']]]]]

編集済み: これは、更新されたパーサーの図で、pyparsing 3.0. 鉄道図

于 2011-01-26T06:50:33.387 に答える
-3

これでうまくいくはずです。私はあなたの例でそれをテストしました:

import re
import ast

def parse(s):
    s = re.sub("[\{\(\[]", '[', s)
    s = re.sub("[\}\)\]]", ']', s)
    answer = ''
    for i,char in enumerate(s):
        if char == '[':
            answer += char + "'"
        elif char == '[':
            answer += "'" + char + "'"
        elif char == ']':
            answer += char
        else:
            answer += char
            if s[i+1] in '[]':
                answer += "', "
    ast.literal_eval("s=%s" %answer)
    return s

さらに必要な場合はコメントしてください

于 2011-01-26T05:01:11.117 に答える