pyparsing不是嵌套列表......为什么?

时间:2010-11-20 05:18:22

标签: python pyparsing

出于某种原因,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 个答案:

答案 0 :(得分:8)

Pyparsing不对这些令牌进行分组,因为您没有告诉它。 Pyparsing的默认行为是将所有匹配的标记简单地串在一起。要对令牌进行分组,请将解析器中的表达式包装在一个pyparsing Group表达式中。在您的情况下,请更改series

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

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

此外,我建议您不要像在series中那样实现自己的逗号分隔列表,而是使用pyparsing helper delimitedList

hand_range = delimitedList(series)

delimitedList假设逗号分隔符,但任何字符(甚至完整的pyparsing表达式)都可以作为delim参数给出。分隔符本身会从结果中被抑制,因为delimitedList假定分隔符只是作为重要位,列表元素之间的分隔符。

完成这两项更改后,解析结果现在开始看起来更像您要求的内容:

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

我猜你也可能想在Group定义周围添加hand,以构建这些结果。

如果这是一个将以某种方式评估的表达式(如扑克手),那么请查看pyparsing wiki上的这些示例,它们使用类作为解析操作来构造可以为rank或boolean计算的对象价值或其他。

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