pyparsing为什么不能嵌套列表?

4

由于某些原因,pyparsing没有对我的字符串进行嵌套列表:

rank = oneOf("2 3 4 5 6 7 8 9 T J Q K A")
suit = oneOf("h c d s")
card = rank + Optional(suit)

suit_filter = oneOf("z o")
hand = card + card + Optional(suit_filter)

greater = Literal("+")
through = Literal("-")
series = hand + Optional(greater | through + hand)

series_split = Literal(",")
hand_range = series + ZeroOrMore(series_split + series)

hand_range.parseString('22+,AKo-ATo,KQz')

>> ['2', '2', '+', ',', 'A', 'K', 'o', '-', 'A', 'T', 'o', ',', 'K', 'Q', 'z']

我不确定为什么pyparsing没有将22+、AKo-ATo和KQz(或更深层次的任何内容)创建为列表。我错过了什么?
1个回答

8
Pyparsing没有对这些标记进行分组,因为您没有告诉它这样做。Pyparsing的默认行为是将所有匹配的标记简单地串联成一个列表。要对标记进行分组,请在解析器中包装要分组的表达式,并使用pyparsing的Group表达式。在您的情况下,将series从以下内容更改为:
series = hand + Optional(greater | through + hand)

series = Group(hand + Optional(greater | through + hand))

此外,我建议您不要像在series中所做的那样实现自己的逗号分隔列表,而是使用pyparsing助手delimitedList
hand_range = delimitedList(series)
delimitedList假定逗号是分隔符,但可以将任何字符(甚至完整的pyparsing表达式)作为delim参数给出。 分隔符本身从结果中被抑制,因为delimitedList假定分隔符只是重要部分之间的分隔符,即列表元素。经过这两个更改,解析结果现在开始看起来更像您所要求的内容:
[['2', '2', '+'], ['A', 'K', 'o', '-', 'A', 'T', 'o'], ['K', 'Q', 'z']]

我猜你可能也想在 hand 定义周围加上 Group,以便对这些结果进行结构化处理。
如果这是一个将要被评估的表达式(比如扑克手牌),请查看 pyparsing 维基上的这些示例,使用类作为解析操作来构造可以评估排名、布尔值或其他内容的对象。

http://pyparsing.wikispaces.com/file/view/invRegex.py

http://pyparsing.wikispaces.com/file/view/simpleBool.py

http://pyparsing.wikispaces.com/file/view/eval_arith.py

如果您为这些表达式构建对象,则不需要使用Group

好的回答,顺便说一下,invRegex.py链接已经失效了。 - shuttle87
Pyparsing不再托管在wikispaces.com上。请前往https://github.com/pyparsing/pyparsing。 - PaulMcG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接