For some reason, pyparsing isn't nesting the list for my string:
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']
I'm not sure why the pyparsing isn't creating lists around 22+, AKo-ATo, and KQz (or any layers deeper than that). What am I missing?
Pyparsing isn't grouping these tokens because you didn't tell it to. Pyparsing's default behavior is to simply string together all matched tokens into a single list. To get grouping of your tokens, wrap the expressions in your parser that are to be grouped in a pyparsing Group
expression. In your case, change series
from:
series = hand + Optional(greater | through + hand)
to
series = Group(hand + Optional(greater | through + hand))
Also, I recommend that you not implement your own comma-delimited list as you have done in series
, but instead use the pyparsing helper, delimitedList
:
hand_range = delimitedList(series)
delimitedList
assumes comma delimiters, but any character (or even complete pyparsing expression) can be given as the delim
argument. The delimiters themselves are suppressed from the results, as delimitedList
assumes that the delimiters are there simply as separators between the important bits, the list elements.
After making these two changes, the parse results now start to look more like what you are asking for:
[['2', '2', '+'], ['A', 'K', 'o', '-', 'A', 'T', 'o'], ['K', 'Q', 'z']]
I'm guessing that you might also want to put Group
around the hand
definition, to structure those results as well.
If this is an expression that will be evaluated in some way (like a poker hand), then please look at these examples on the pyparsing wiki, which use classes as parse actions to construct objects that can be evaluated for rank or boolean value or whatever.
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
If you construct objects for these expressions, then you won't need to use Group
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With