Pyparsing не вкладывает список ... Почему?
Вопрос
По какой-то причине Pyparding не вложил в список для моей строки:
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']
Я не уверен, почему Pyparding не создает списки около 22+, AKO-ATO и KQZ (или любых слоев глубже, чем это). Что мне не хватает?
Решение
Pyparding не группирует эти токены, потому что вы этого не сказали. Поведение по умолчанию Pyparding - просто строка вместе все совпадающие токены в один список. Чтобы получить группировку ваших токенов, оберните выражения в своем парсере, которые должны быть сгруппированы в пипсере Group
выражение. В вашем случае изменить series
от:
series = hand + Optional(greater | through + hand)
к
series = Group(hand + Optional(greater | through + hand))
Кроме того, я рекомендую вам не реализовать свой собственный список для запятой, как вы сделали в series
, но вместо этого используйте Pyparding Helper, delimitedList
:
hand_range = delimitedList(series)
delimitedList
предполагает, что делимители запяты, но любой символ (или даже полное выражение Pyparding) может быть дано как delim
аргумент Сами разграничители подавляются из результатов, как delimitedList
Предполагается, что разделители там просто в качестве сепараторов между важными битами, элементами списка.
После выполнения этих двух изменений результаты анализа теперь начинают больше похожи на то, что вы просите:
[['2', '2', '+'], ['A', 'K', 'o', '-', 'A', 'T', 'o'], ['K', 'Q', 'z']]
Я предполагаю, что вы также можете поставить Group
вокруг hand
Определение, а также структурировать эти результаты.
Если это выражение, которое будет оцениваться в некотором роде (например, покерная рукой), то, пожалуйста, посмотрите на эти примеры на Pyparding 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
.