2013-05-20 20 views
5

Ich habe heute Abend angefangen, pyparsing zu verwenden und ich habe eine komplexe Grammatik erstellt, die einige Quellen beschreibt, mit denen ich sehr effektiv arbeite. Es war sehr einfach und sehr kraftvoll. Allerdings habe ich Probleme mit ParsedResults zu arbeiten. Ich muss über verschachtelte Token in der Reihenfolge iterieren können, in der sie gefunden wurden, und ich finde es ein wenig frustrierend. Ich habe mein Problem zu einem einfachen Fall abstrahiert:`pyparsing`: Iterieren über` 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() 

soweit ich sehen kann, dies sollte arbeiten? Hier ist die Ausgabe:

<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' 

Die XML-Ausgabe scheint darauf hinzudeuten, dass die Zeichenfolge genau analysiert wird, wie ich es wünsche, aber ich kann nicht über den Satz wiederholen, zum Beispiel, es zu rekonstruieren.

Gibt es eine Möglichkeit zu tun, was ich brauche?

Danke!

edit:

Ich habe das schon mit:

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

aber es hilft mir nicht allzu viel, weil ich nicht verschiedene Arten von String unterscheiden kann. Hier ist ein leicht erweiterte Beispiel:

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 

der Ausgang ist:

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

nicht allzu hilfreich. Ich kann nicht zwischen word und number unterscheiden, und das direct_speech Element ist mit word gekennzeichnet?!

Ich vermisse offensichtlich etwas. Alles, was ich tun möchte, ist:

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

sollte ich das anders nähern?

Antwort

1

gut, ich habe jetzt eine Reihe von verschiedenen Ansätzen versucht, und ich kann nicht bekommen, was ich brauche, so (absurd, obwohl es scheint), ich bin mit .asXML() und Parsing das resultierende XML.Hier ist mein Beispiel:

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 

die Ausgänge:

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

scheint wie ein langer Weg, um die Häuser, aber es scheint nicht, einen besseren Weg zu sein.

5

r.sentence enthält eine Mischung aus Zeichenfolgen und ParseResults, und nur ParseResults unterstützt getName(). Haben Sie versucht, nur über r.sentence zu iterieren? Wenn ich es Drucke mit aus asList(), erhalte ich:

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

Oder dieser Schnipsel:

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

Gibt:

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

Ich bin mir nicht sicher, ob ich Ihre Frage beantwortet, Aber wirft das Licht auf die nächsten Schritte?

(Willkommen bei Pyparsing)