2013-05-20 19 views
5

私は今晩pyparsingを使い始めました。私は非常に効果的に働いているいくつかのソースを記述する複雑な文法を作りました。それは非常に簡単で非常に強力でした。しかし、私はParsedResultsと一緒に働くことにいくつかの問題を抱えています。ネストされたトークンを発見した順に反復処理できるようにする必要があります。私はそれを少しイライラしています。私は単純なケースに私の問題を抽象化しました:`pyparsing`:` ParsedResults`を繰り返します

import pyparsing as pp 

word = pp.Word(pp.alphas + ',.')('word*') 
direct_speech = pp.Suppress('“') + pp.Group(pp.OneOrMore(word))('direct_speech*') + pp.Suppress('”') 
sentence = pp.Group(pp.OneOrMore(word | direct_speech))('sentence') 

test_string = 'Lorem ipsum “dolor sit” amet, consectetur.' 

r = sentence.parseString(test_string) 

print r.asXML('div') 

print '' 

for name, item in r.sentence.items(): 
    print name, item 

print '' 

for item in r.sentence: 
    print item.getName(), item.asList() 

私が見る限り、これはうまくいくはずですか?ここでは、出力は次のようになります。

<div> 
    <sentence> 
    <word>Lorem</word> 
    <word>ipsum</word> 
    <direct_speech> 
     <word>dolor</word> 
     <word>sit</word> 
    </direct_speech> 
    <word>amet,</word> 
    <word>consectetur.</word> 
    </sentence> 
</div> 

word ['Lorem', 'ipsum', 'amet,', 'consectetur.'] 
direct_speech [['dolor', 'sit']] 

Traceback (most recent call last): 
    File "./test.py", line 27, in <module> 
    print item.getName(), item.asList() 
AttributeError: 'str' object has no attribute 'getName' 

XML出力は、私が望むと同じように、文字列が正確に解析されることを示していると思われるが、私はそれを再構築するために、例えば、文を反復することはできません。

私が必要とする方法はありますか?

ありがとうございます!

編集:

私はこの使用してきた:

for item in r.sentence: 
    if isinstance(item, basestring): 
     print item 
    else: 
     print item.getName(), item 

をしかし、私は、文字列の異なる種類を区別することはできませんので、それは、すべてのことずっと私を助けていません。ここでは、わずかに拡大例は次のとおりです。

word = pp.Word(pp.alphas + ',.')('word*') 
number = pp.Word(pp.nums + ',.')('number*') 

direct_speech = pp.Suppress('“') + pp.Group(pp.OneOrMore(word | number))('direct_speech*') + pp.Suppress('”') 
sentence = pp.Group(pp.OneOrMore(word | number | direct_speech))('sentence') 

test_string = 'Lorem 14 ipsum “dolor 22 sit” amet, consectetur.' 

r = sentence.parseString(test_string) 

for i, item in enumerate(r.sentence): 
    if isinstance(item, basestring): 
     print i, item 
    else: 
     print i, item.getName(), item 

出力は、次のとおりです。あまりにも便利

0 Lorem 
1 14 
2 ipsum 
3 word ['dolor', '22', 'sit'] 
4 amet, 
5 consectetur. 

ません。 wordnumberを区別できず、direct_speech要素にはwordというラベルが付けられています。

私は明らかに何かが不足しています。私がしたいのは次のとおりです:

for item in r.sentence: 
    if (item is a number): 
     do something 
    elif (item is a word): 
     do something else 
etc. ... 

私はこれに違って接近するべきですか?

答えて

1

だけでなく、私は今、多くの異なるアプローチを試みたと私は私が必要なものを得ることができないので、(それはそうけれども不条理)、私は.asXML()と解析を使用しています結果のXML

word : Lorem 
number : 14 
word : ipsum 
direct_speech 
    word : dolor 
    number : 22 
    word : sit 
word : amet, 
word : consectetur. 

は、家の周りの長い道のりのように思えるが、より良い方法があるとは思えない:出力

import pyparsing as pp 

word = pp.Word(pp.alphas + ',.')('word*') 
number = pp.Word(pp.nums + ',.')('number*') 
direct_speech = pp.Suppress('“') + pp.Group(pp.OneOrMore(word | number))('direct_speech*') + pp.Suppress('”') 
sentence = pp.Group(pp.OneOrMore(word | number | direct_speech))('sentence') 

test_string = 'Lorem 14 ipsum “dolor 22 sit” amet, consectetur.' 
r = sentence.parseString(test_string) 

from lxml import etree 
xml = etree.fromstring(r.sentence.asXML('sentence')) 
for el in xml: 
    if len(el): 
     print el.tag 
     for sub_el in el: 
      print ' ', sub_el.tag, ':', sub_el.text 
    else: 
     print el.tag, ':', el.text 

:ここに私の例です。

5

r.sentenceには、文字列とParseResultsの組み合わせが含まれており、ParseResultsのみがgetName()をサポートしています。 r.sentenceを反復してみましたか?私はasList()を使用して、それをプリントアウトした場合は、私が手:

['Lorem', 'ipsum', ['dolor', 'sit'], 'amet,', 'consectetur.'] 

それともこのスニペット:

for item in r.sentence: 
    print type(item),item.asList() if isinstance(item,pp.ParseResults) else item 

を与える:

<type 'str'> Lorem 
<type 'str'> ipsum 
<class 'pyparsing.ParseResults'> ['dolor', 'sit'] 
<type 'str'> amet, 
<type 'str'> consectetur. 

私は私はあなたの質問に答えわからないんだけど、しかし、それは次のどこに行くべきかについて何らかの光を当てていますか?

(Pyparsingへようこそ)