我正在尝试编写解析器来处理来自注册商API的响应数据。格式不是我之前见过的格式,所以这可能很容易;如果有人认出它,请告诉我,可能有一个预先存在的库来处理它。但是现在我的运作假设我自己需要解析它。
我的语法看起来像这样:
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
当我运行这个简单的测试用例时:
rsp = 'username=goat; errors={username=[already taken, too short]}; empty_field='
result = response.parseString(rsp)
print result.asDict()
我得到以下内容:
{'username': 'goat', 'empty_field': '', 'errors': {'username': {}}}
错误[&#39;用户名&#39;]应该是字符串列表,但显示为空字典。当我.dump()params,看起来一切都很好:
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
我在这里做错了什么?
答案 0 :(得分:0)
在当前版本的pyparsing中,它是asDict()
的天真实现。在yoru语法中,您可以创建两种不同样式的ParseResults:具有名称的结果和仅作为普通列表的结果。 asList()
只是遍历嵌套的ParseResults获取列表和子列表,因此asDict()
的工作方式类似。但是,asDict()
确实需要对可能存在的值类型更加智能 - 目前,这是pyparsing中的一个错误。
修改强>
要解决此问题,您需要做一些工作来将列表存储为实际列表,而不是ParseResults。将values
表达式重新定义为:
values = delimitedList(value, ",").setParseAction(lambda toks: [toks.asList()])
因为这会将解析后的列表作为ParseResults返回,但作为实际列表,toDict()
将不会尝试将其转换为dict。