我想使用pyparsing来解析表单的表达式:expr = '(gimme [some {nested [lists]}])'
,然后返回一个表单的python列表:[[['gimme', ['some', ['nested', ['lists']]]]]]
。现在我的语法看起来像这样:
nestedParens = nestedExpr('(',')')
nestedBrackets = nestedExpr('[',']')
nestedCurlies = nestedExpr('{','}')
enclosed = nestedParens | nestedBrackets | nestedCurlies
目前,enclosed.searchString(expr)
会返回表单列表:[[['gimme', ['some', '{nested', '[lists]}']]]]
。这不是我想要的,因为它不能识别正方形或花括号,但我不知道为什么。
答案 0 :(得分: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']]]]]
已更新:我发布了上述解决方案,因为我实际上是在一年前写的。我只是仔细看看你的原始帖子,它让我想到了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']]]]]
答案 1 :(得分:-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
评论是否需要更多