2010-11-20 5 views
4

Aus irgendeinem Grunde pyparsing nistet nicht die Liste für meinen string:pyparsing ist keine nistliste ... warum?

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'] 

Ich bin nicht sicher, warum die pyparsing Listen um 22+, AKo-ATo und KQz nicht (oder jegliche Schaffung Schichten tiefer als das). Was vermisse ich?

Antwort

8

Pyparsing gruppiert diese Tokens nicht, weil Sie es nicht angegeben haben. Das Standardverhalten von Pyparsing besteht darin, alle übereinstimmenden Token einfach in einer einzigen Liste zusammenzufassen. Um die Gruppierung Ihrer Token zu erhalten, umschließen Sie die Ausdrücke in Ihrem Parser, die in einem pyparierenden Group Ausdruck gruppiert werden sollen.

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

zu

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

, empfehle ich auch, dass Sie Ihre eigene kommagetrennte Liste nicht implementieren, wie Sie in series getan haben, sondern stattdessen die pyparsing Helfer verwenden: In Ihrem Fall series von ändern , delimitedList:

hand_range = delimitedList(series) 

delimitedList annimmt comma Begrenzer, aber jedes Zeichen (oder sogar vollständiger pyparsing expression) kann als das delim Argument angegeben werden. Die Delimiter selbst werden von den Ergebnissen unterdrückt, da delimitedList davon ausgeht, dass die Delimiter einfach als Trennzeichen zwischen den wichtigen Bits, den Listenelementen, stehen.

Nachdem diese beiden Änderungen vorgenommen haben, beginnen die Parse-Ergebnisse nun mehr aussehen wie das, was Sie fordern:

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

Ich vermute, dass Sie auch Group um die hand Definition setzen möchten, zu Strukturieren Sie diese Ergebnisse auch.

Wenn dies ein Ausdruck ist, der auf irgendeine Art ausgewertet wird (wie ein Pokerblatt), dann schaue dir diese Beispiele im pyparsing Wiki an, die Klassen als Parseaktionen verwenden, um Objekte zu erstellen, die nach Rang oder Rang ausgewertet werden können Boolescher Wert oder was auch immer.

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

Wenn Sie Objekte für diese Ausdrücke konstruieren, dann müssen Sie nicht Group verwenden.

+0

Gute Antwort, FYI der 'invRegex.py' Link ist tot. – shuttle87