简体   繁体   English

python 列表(嵌套)解析器在 pyparsing 中看起来像什么?

[英]What would a python list (nested) parser look like in pyparsing?

I would like to understand how to use pyparsing to parse something like a nested Python list.我想了解如何使用 pyparsing 来解析类似嵌套 Python 列表的内容。 This is a question to understand pyparsing.这是一个理解pyparsing的问题。 Solutions that circumvent the problem because the list of the example might look like JSON or Python itself should not prevent the usage of pyparsing.由于示例列表可能看起来像 JSON 或 Python 本身而规避问题的解决方案不应阻止 pyparsing 的使用。

So before people start throwing json and literal_eval at me let's consider a string and result that looks like this:因此,在人们开始向我抛出 json 和 literal_eval 之前,让我们考虑一个如下所示的字符串和结果:

Input:
{1,2,3,{4,5}}
Expected Output (Python list):
[1,2,3,[4,5]]

I currently have this code but the output does not parse the nested list我目前有这段代码,但 output 不解析嵌套列表

import pyparsing


print(
    pyparsing.delimited_list(
        pyparsing.Word(pyparsing.nums) | pyparsing.nested_expr("{", "}")
    )
    .parse_string("{1,2,3,{4,5}}")
    .as_list()
)
# [['1,2,3,', ['4,5']]]

There is pretty much the same question here already but this one was circumvented by using json parsing: Python parse comma seperated nested brackets using Pyparsing这里已经有几乎相同的问题,但是这个问题是通过使用 json 解析来规避的: Python parse comma separated nested brackets using Pyparsing

You need to use a Forward reference , since your logic is recursive.您需要使用Forward reference ,因为您的逻辑是递归的。 It's impossible to use something you haven't defined before, hence the Forward object allows you to do just that:不可能使用你之前没有定义的东西,因此Forward object 允许你这样做:

expr = pyparsing.Forward()
expr <<= pyparsing.delimited_list(
    pyparsing.Word(pyparsing.nums) | pyparsing.nested_expr("{", "}", expr)
)

print(expr.parse_string("{1,2,3,{4,5}}").as_list())
# [['1', '2', '3', ['4', '5']]]

This answer also has another good example of how to use them.这个答案还有另一个很好的例子来说明如何使用它们。

Thanks to the answer from Xiddoc I was able to slightly adjust the answer to also work when the expression starts with a list (no idea why the solution with nested_expr does not work)感谢Xiddoc 的回答,我能够稍微调整答案以在表达式以列表开头时也起作用(不知道为什么带有 nested_expr 的解决方案不起作用)

import pyparsing as pp


expr = pp.Forward()
group_start, group_end = map(pp.Suppress, r"{}")

number = pp.Word(pp.nums).setParseAction(lambda s, l, t: int(t[0]))
nested_list = pp.Group(group_start + expr[...] + group_end)
expr <<= pp.delimited_list(number | nested_list)

print(expr.parse_string(r"{{1},2,3,{4,5}}", parse_all=True).as_list()[0])
# [[1],2,3,[4,5]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM