2012-12-01 12 views
6

私はPyparsingを使い慣れていません。私は何が間違っているのかを説明する最も単純な形式に問題を減らそうとしました。(おそらくPyparsingは必要ないでしょう)トークンを変更するnewbie setParseActionをパースします

文字と数字からなる文字列があるとします例えば、 "b7 z4 a2 de c3"とすることができる。常に手紙がありますが、番号は任意です。これを個々の要素に分解して処理したいのですが、番号のない裸の手紙がある場合は、それを変更して後に「デフォルト」番号1を付けると便利です。そして、すべての要素を一貫した方法で処理することができました。

from pyparsing import * 
teststring = "a2 b5 c9 d e z" 
expected_letter = Word("ABCDEFGabcdefgzZxy", exact=1) 
expected_number = Word(nums) 
letter_and_number = expected_letter + expected_number 
bare_letter = expected_letter 
bare_letter.setParseAction(lambda s,l,t: t.append("1")) 
elements = letter_and_number | bare_letter 
line = OneOrMore(elements) 
print line.parseString(teststring) 

は残念ながら、t.appendは()私は、「1」のリストに追加するあった、期待してい何をしていません。次のように私は、私がsetparseActionでこれを行うことができると思いました解析されたトークン。代わりに、私はエラーが発生します:TypeError: 'str'オブジェクトは呼び出し可能ではありません。

私はおそらく、ここでは本当に厚いですが、あなたの1人の専門家が私をまっすぐにしてください。

スティーブ

答えて

4

おかげでpyparsingについて取得するための基本的な概念の1つは、それが文字列のちょうどリストでは動作しないということですが、ParseResultsオブジェクトに解析作品を組み立てます。 ParseResultsは、定義された結果名を持つParserElementから解析されたトークンがある場合、リストとしてアクセスできるdypsまたはオブジェクトとして、pyparsingで定義された豊富なデータ型です。

ただし、ParseResultsは簡単にアクセスできるように設計されていますが、更新が制限されています。内部的には、pyparsingでは、一致する各式は小さなParseResultsオブジェクトを作成します。これが大きな式の一部である場合、その式は、+ =演算子を使用して断片を大きなParseResultsに累積します。あなたのケースでは

、あなたは「1」を含む小さなParseResultsを作成するとtに追加して渡されParseResultsに追加することができます

t += ParseResults("1") 

残念ながら、これはラムダとして動作しません。 - あなたが試すことができる

lambda s,l,t: t.__iadd__(ParseResults("1")) 

しかし、これはちょっと賢い感じです。

また、オプションクラスを利用するには、パーサーを少し考え直すこともできます。あなたの末尾の桁をオプションの要素と考えてください。そのため、要素がない場合に備えてデフォルト値を定義することができます。など

(通常は、検索文字列を返す、

>>> letter = Word(alphas,exact=1) 
>>> digit = Word(nums,exact=1) 
>>> teststring= "a2 b5 c9 d e z" 
>>> letter_and_digit = Combine(letter + Optional(digit, default="1")) 
>>> print (sum(letter_and_digit.searchString(teststring))) 
['a2', 'b5', 'c9', 'd1', 'e1', 'z1'] 

がそうでなければ、各試合は['a','2'], ['b','5']ようになり、文字列に別の文字と数字を再参加するために使用されコンバイン:私はあなただけであなたが望むものを定義することができると思います1つの要素リストのリストのようなParseResultsオブジェクトのリストsearchStringの結果をsumに渡すことで、これらがすべて1つのParseResultsに追加されます)

+0

ああ、それは今完璧な意味があります!解析結果をプリントアウトすると、通常のリストのように見えたので、通常の方法で追加することができたと思いました。また、オプションでデフォルト設定が可能であるという事実を忘れていました。そして、私の実際のプログラムにも適用されます。これは、ここでは取り除かれたバージョンより少し複雑です。あなたの助け...とPyparsing自体のために多くのおかげで!スティーブ –