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

标签 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(或任何比这更深的层)创建列表。我错过了什么?

最佳答案

Pyparsing 不会对这些标记进行分组,因为您没有告诉它这样做。 Pyparsing 的默认行为是将所有匹配的标记简单地串在一起到一个列表中。要对您的 token 进行分组,请将要在 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']]

我猜您可能还想将 Group 放在 hand 定义周围,以构建这些结果。

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

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

关于python - pyparsing 不是嵌套列表......为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4231349/

相关文章:

python - 如何在 pyparsing 中指定 token 顺序?

python - Pyparsing 在不同机器上的行为不同

python - Matplotlib 累积图

php - 如何运行包含来自 heroku 上托管的 php 库的 python 脚本?

python - 在 BeautifulSoup 中查找标签和文本

python - 解析特殊字符旁边的关键字(pyparsing)

python - 使用 while 循环重复生成随机数的函数

python - 使用要点从 python 生成 pdf 报告

python - pyparsing 条件解析器

python - 是否可以使用 pyparsing 解析非平凡的 C 枚举?