Python 如何使用pyparsing解析具有多个opener/closer类型的嵌套表达式?

Python 如何使用pyparsing解析具有多个opener/closer类型的嵌套表达式?,python,pyparsing,Python,Pyparsing,我想使用pyparsing来解析以下形式的表达式:expr='(给我[some{nested[lists]}]),并获取以下形式的python列表:[[[[['gimme',['some',['nested',['lists']]。现在我的语法是这样的: nestedParens=nestedExpr(“(”,“)”) Nested括号=nestedExpr(“[”,“]”) nestedCurlies=nestedExpr('{','}') 封闭=嵌套括号|嵌套括号|嵌套卷曲 目前,inclu

我想使用pyparsing来解析以下形式的表达式:
expr='(给我[some{nested[lists]}])
,并获取以下形式的python列表:
[[[[['gimme',['some',['nested',['lists']]
。现在我的语法是这样的:

nestedParens=nestedExpr(“(”,“)”)
Nested括号=nestedExpr(“[”,“]”)
nestedCurlies=nestedExpr('{','}')
封闭=嵌套括号|嵌套括号|嵌套卷曲


目前,
included.searchString(expr)
返回一个表单列表:
[[[['gimme',['some','{nested','[lists]}]]]
。这不是我想要的,因为它无法识别方括号或花括号,但我不知道为什么。

这应该能帮到你。我在您的示例中进行了测试:

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

如果需要更多注释

这里有一个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()
更新:我发布了上述解决方案,因为我在一年多前就把它作为一个实验写了出来。我只是仔细看了一下你原来的帖子,它让我想到了由
operatorPrecedence
方法创建的递归类型定义,因此我使用你原来的方法重新定义了这个解决方案-更简单!(但右侧输入数据可能存在左侧递归问题,未经过彻底测试):

编辑: 下面是使用pyparsing 3.0中提供的铁路图支持更新的解析器的示意图。

很抱歉说得不够清楚,但我提到的输出是一个嵌套的python列表,这是使用pyparsing解析嵌套表达式的常见结果。您的解决方案只返回一个类似于打印的python列表的字符串。谢谢你的帮助@德里克:我没有返回字符串。我正在返回一份清单。名为answer的变量是字符串,yes;但这就是为什么有一行写着exec“s=%s”%answer的原因。这将创建一个名为s的新变量,它是一个列表。这就是为什么我的代码返回s而不是答案。您应该检查返回值的类型,您将看到它是一个列表,而不是一个字符串您正在返回一个列表,但我认为您误解了在这种上下文中解析是什么。解析字符串时,您通常可以在解析时访问匹配的令牌/组,从而允许您对它们执行某些操作。您的程序只是动态生成python代码并执行它以将字符串转换为嵌套列表。它不解析任何东西,也不使用原始问题中提到的pyparsing。更不用说它将执行任意的python代码,因此它在输入时会失败,例如,带引号的输入。最多,您应该使用
ast.literal\u eval
。危险的使用exec——数据可能会运行代码删除磁盘上的文件、上载敏感信息等。Paul,非常感谢您提供了信息丰富的答案。更感谢您创建并开放我最喜欢的python库!pyparsing帮助我大大降低了我所从事项目的规模、复杂性和可维护性
[['gimme', ['some', ['nested', ',', 'nested', ['lists']]]]]
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']]]]]