提问人:Sergej Herbert 提问时间:12/28/2022 更新时间:12/29/2022 访问量:65
python 列表(嵌套)解析器在 pyparsing 中会是什么样子?
What would a python list (nested) parser look like in pyparsing?
问:
我想了解如何使用 pyparsing 来解析嵌套的 Python 列表之类的东西。 这是一个需要理解pyparsing的问题。由于示例列表可能看起来像 JSON 或 Python 本身而规避该问题的解决方案不应阻止使用 pyparsing。
因此,在人们开始向我抛出 json 和 literal_eval 之前,让我们考虑一个字符串和结果,如下所示:
Input:
{1,2,3,{4,5}}
Expected Output (Python list):
[1,2,3,[4,5]]
我目前有这段代码,但输出没有解析嵌套列表
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']]]
这里已经有几乎相同的问题,但这个问题通过使用 json 解析来规避: Python 使用 Pyparsing 解析逗号分隔的嵌套括号
答:
3赞
Xiddoc
12/28/2022
#1
您需要使用正向引用,因为您的逻辑是递归的。不可能使用以前未定义过的内容,因此该对象允许您这样做:Forward
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']]]
这个答案还有另一个关于如何使用它们的好例子。
评论
0赞
Sergej Herbert
12/28/2022
看起来不错。但是你知道为什么这个输入会失败吗?"{{1},2,3,{4,5}}"
0赞
Sergej Herbert
12/29/2022
#2
多亏了 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]]
评论