如何让pyparsing的as_dict()方法返回嵌套字典解析结果?
pyparsing解析生成嵌套字典结果的实现方法
要得到你期望的嵌套结构解析结果,需要修正原代码的3个核心问题:
- 语法存在递归依赖(
object可包含tuple,tuple又由object组成),原代码先定义object再覆盖变量的写法,会导致tuple引用旧版object规则,递归解析失效 - tuple的左右括号没有做屏蔽处理,会作为冗余内容出现在解析结果中
- 没有使用前向引用类处理递归语法,导致解析结果层级被打平,子节点字段直接泄漏到最外层
修正后代码
parser.py
import pyparsing as pp class parser: def __init__(self): # 先声明前向引用,处理object和tuple的递归依赖 self.object = pp.Forward() self.integer = pp.Word(pp.nums).set_results_name('int') self.string1 = pp.QuotedString(quoteChar='"') self.string2 = pp.QuotedString(quoteChar="'") self.string = pp.Or([self.string1, self.string2]).set_results_name('str') # 用Suppress屏蔽括号,避免括号出现在最终结果中 self.tuple = ( pp.Suppress('(') + pp.delimited_list(self.object, delim=',') + pp.Suppress(')') ).set_results_name('tuple') # 给前向引用的object绑定实际匹配规则 self.object <<= pp.Or([self.string, self.integer, self.tuple]) self.varname = pp.Word(pp.alphas + "_").set_results_name('varname') self.let_ = pp.Keyword('let') self.const_ = pp.Keyword('const') self.var_ = pp.Keyword('var') self.set_ = pp.one_of([":", "="]) self.variable = pp.Or([ pp.Or([self.let_, self.const_, self.var_]) + self.varname + self.set_ + self.object, self.varname + self.set_ + self.object ]) def parseVar(self, string): return self.variable.parse_string(string)
main.py无需修改,运行后输出:
{'varname': 'hi', 'tuple': {'str': 'hi', 'int': '2'}}
和你期望的结构完全一致,支持tuple多层嵌套(比如tuple内再包含tuple)。
注意事项
如果tuple中会出现多个同类型元素(比如两个字符串、两个整数),默认
set_results_name只会保留最后一个匹配到的同名字段。如果需要收集所有同类型元素,在定义字段时加上list_all_matches=True参数即可,例如:self.integer = pp.Word(pp.nums).set_results_name('int', list_all_matches=True) self.string = pp.Or([self.string1, self.string2]).set_results_name('str', list_all_matches=True)此时解析
hi = ("a", "b", 1, 2)会得到{'varname': 'hi', 'tuple': {'str': ['a', 'b'], 'int': ['1', '2']}}的结构。
内容的提问来源于stack exchange,提问作者thatrandomperson
相关产品推荐
相关产品推荐

