2010-11-20 74 views
4

出于某种原因,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(或任何比那更深的层)。我错过了什么?

回答

8

因为您没有告诉它,因此Pyparsing不会分组这些标记。 Pyparsing的默认行为是将所有匹配的记号简单地串到一个列表中。要获得令牌的分组,请在您的分析器中包装表达式,并将其分组到表达式中。在你的情况,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上的这些示例,这些示例使用类作为分析动作来构建可评估等级的对象布尔值或其他。

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

+0

好的答案,只是'invRegex.py'链接已经死了。 – shuttle87 2015-06-23 23:29:42