2010-11-20 98 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