Python 为什么pyparser';s asDict()返回空的dict而不是列表?
我正试图编写一个解析器来处理来自注册器API的响应数据。这种格式不是我以前见过的,所以这可能真的很容易;如果有人认识到它,请告诉我,可能有一个预先存在的库来处理它。但现在我的操作假设是我需要自己解析它 我的语法是这样的:Python 为什么pyparser';s asDict()返回空的dict而不是列表?,python,parsing,pyparsing,Python,Parsing,Pyparsing,我正试图编写一个解析器来处理来自注册器API的响应数据。这种格式不是我以前见过的,所以这可能真的很容易;如果有人认识到它,请告诉我,可能有一个预先存在的库来处理它。但现在我的操作假设是我需要自己解析它 我的语法是这样的: equals = Literal("=").suppress() lbracket = Literal("[").suppress() rbracket = Literal("]").suppress() lbrace = Literal("{").suppress() rbr
equals = Literal("=").suppress()
lbracket = Literal("[").suppress()
rbracket = Literal("]").suppress()
lbrace = Literal("{").suppress()
rbrace = Literal("}").suppress()
value_dict = Forward()
value_list = Forward()
value_string = Word(alphanums + "@. ")
value = value_list ^ value_dict ^ value_string
values = Group(delimitedList(value, ","))
value_list << lbracket + values + rbracket
identifier = Word(alphanums + "_.")
assignment = Group(identifier + equals + Optional(value))
assignments = Dict(delimitedList(assignment, ';'))
value_dict << lbrace + assignments + rbrace
response = assignments
我得到以下信息:
{'username': 'goat', 'empty_field': '', 'errors': {'username': {}}}
errors['username']应该是字符串列表,但显示为空dict。当I.dump()调用参数时,看起来一切正常:
ss = response.searchString(rsp)
for i in ss:
print i.dump()
收益率:
- empty_field:
- errors: [['username', ['already taken', 'too short']]]
- username: ['already taken', 'too short']
- username: goat
我做错了什么?在当前版本的pyparsing中,它是
asDict()
的简单实现。在yoru语法中,您可以创建两种不同样式的ParseResults:带名称的结果和只是普通列表的结果asList()
只是在嵌套的ParseResults中迭代,以获取列表和子列表,因此asDict()
的工作原理类似。然而,asDict()
确实需要对可能存在的值的类型更聪明一点——目前,这是pyparsing中的一个错误
编辑
为了解决这个问题,您需要做一些工作,将列表存储为实际列表,而不是解析结果。将值
表达式重新定义为:
values = delimitedList(value, ",").setParseAction(lambda toks: [toks.asList()])
由于这将返回解析后的列表,而不是作为ParseResults,而是作为实际列表,
toDict()
将不会尝试将其转换为dict。您是否立即知道我可以做些什么来解决此问题?我真的不希望编写一个递归迭代器来遍历整个数据集并“修复”没有返回预期结果的东西。事实证明,这种递归版本的toDict()
并不是那么容易。我会仔细考虑一下,希望尽快将一个更智能的toDict
版本签入SVN。更新后的版本带有对asDict()的修复,以正确识别dict和unkeed列表,签入SVN
values = delimitedList(value, ",").setParseAction(lambda toks: [toks.asList()])