#python #pyparsing
#python #pyparsing
Вопрос:
Основываясь на этой грамматике:
from pyparsing import *
g = quotedString.setParseAction( removeQuotes )
eg = Suppress('-') quotedString.setParseAction( removeQuotes )
choice = Or( [ g.setResultsName("out",listAllMatches=True),
eg.setResultsName("in",listAllMatches=True) ] )
grammar = ZeroOrMore( choice ) Suppress(restOfLine)
a = world.parseString( ' "ali" -"baba" "holy cow" -"smoking beaute" ' )
print a.dump()
Я обнаружил, что токены, которые удовлетворяют eg
нетерминальному параметру, всегда помещаются в дополнительный список. Единственное отличие от g
заключается в том, что у него есть ведущее `Suppress(‘-‘)’.
['ali', 'baba', 'holy cow', 'smoking beaute']
- in: [['baba'], ['smoking beaute']]
- out: ['ali', 'holy cow']
Как заставить их вести себя одинаково? Я хочу добиться результата, приведенного ниже:
['ali', 'baba', 'holy cow', 'smoking beaute']
- in: ['baba', 'smoking beaute']
- out: ['ali', 'holy cow']
Комментарии:
1. Здесь нет причин для использования Or, первое совпадение является однозначным и лучше справляется с коротким замыканием. Мне также жаль видеть, что синтаксис оператора вам не по вкусу, я думаю, это действительно улучшает читаемость грамматик — но каждому свое.
2. Следующий выпуск pyparsing позволит вам задавать имена результатов с помощью listAllMatches=True, используя форму:
choice = Or( [ g("out*"),eg("in*")] )
Действительно ли это предпочтительнееchoice = g("out*") | eg("in*")
? Ну, это ваш код…
Ответ №1:
Прошло некоторое время с тех пор, как я рассматривал эту проблему — проблема в том, что И всегда возвращают свои токены в виде списков, даже если содержат только одно значение.
Вот разгруппировка, которая может прояснить это для вас, я включу это в следующий выпуск pyparsing:
ungroup = lambda expr : TokenConverter(expr).setParseAction(lambda t:t[0])
eg = ungroup(Suppress('-') quotedString.setParseAction( removeQuotes ))
С вашим тестовым кодом я теперь получаю эти результаты:
['ali', 'baba', 'holy cow', 'smoking beaute']
- in: ['baba', 'smoking beaute']
- out: ['ali', 'holy cow']
Комментарии:
1. Мне удалось устранить проблему, добавив выражение Combine to quoteString. Но помощник по разгруппировке действительно выглядит полезным.