Russell Borogoveが言うように、同じ解析レベルにある場合、名前付きの結果は一意である必要があります。同じタイプの2つ以上の名前付き要素(たとえば、2つの「テキスト」または2つの「ラテックス」)を含む「行」を作成することはできません。これらは両方とも、基になるディクショナリで同じキーを使用するためです。listAllMatches
最新のPyParsingのソリューションについては、Paul McGuireが書いたとおりに見て、すべてを延期します:)
「latex_h」または「reg_text」に解析アクションをアタッチすることでこれを回避することもできますが、「latex_h」要素に兄弟の「reg_text」要素の知識が必要な場合、これは役に立ちません。その場合、おそらく文法をもう少し分割するか、ツリーベースのアプローチを使用して解析する必要があります(最下位の要素からルートまで、解析アクションによって、および/または結果のリストを反復処理することによって) 、辞書ベースのアプローチではなく。
解析ツリーが「犬」を残さなかったことに注意することが重要です。正しく解析されました。解析された結果が辞書に割り当てられなかっただけです。次のように、解析された値にアクセスできます。sol.line[0]
「latex」と「cat」が「line」の外に表示される理由については、OneOrMore定義をGroup()内に配置する必要があります。
reg_text
これは、要素が解析されるときに(のような親要素が解析されるときではなく)要素に解析アクションを適用する例grammar
です。それはあなたが抱えている「名前付き結果」の問題を解決しませんが、パーサーで何を達成しようとしているのかについての文脈がなければ、解決策を提案することはできません。
from pyparsing import *
latex_h = QuotedString("$")('latex')
reg_text = Word(alphas)('text')
grammar = Group(OneOrMore( latex_h | reg_text ))('line')
def parse_reg_text(s, loc, toks):
if toks.text == 'dog':
return "atomic " + toks.text
else:
return "ninja " + toks.text
reg_text.setParseAction(parse_reg_text)
sol = grammar.parseString('''dog $x^2$ cat $y^3$''')
print sol.dump()
これにより、次の出力が得られます。
[['atomic dog', 'x^2', 'ninja cat', 'y^3']]
- line: ['atomic dog', 'x^2', 'ninja cat', 'y^3']
- latex: y^3
- text: ninja cat