2013-05-20 12 views
5

Bu akşam pyparsing'u kullanmaya başladım ve çok etkili bir şekilde çalıştığım bazı kaynakları tanımlayan karmaşık bir dilbilgisi yapıyorum. Çok kolay ve çok güçlüydü. Ancak, ParsedResults ile çalışmakta sorun yaşıyorum. İç içe geçmiş belirteçleri buldukları sırayla yineleyebilmem gerekir ve bunu biraz sinir bozucu buluyorum. Sorunumu basit bir durumla ifade ettim: Görebildiğim kadarıyla, bu işe yaramalı mıyım? İşte çıktı şöyledir:`pyparsing`: 'ParsedResults` üzerinde yineleme

<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 çıktı keşke gibi dize aynen ayrıştırılır belirtmek görünüyor, ama bunu yeniden, örneğin, cümlenin üzerinde yineleme olamaz.

İhtiyacım olanı yapmanın bir yolu var mı?

Teşekkürler!

düzenleme:

Bunu kullanıyorum: Ben dize farklı türde ayıramadığından

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

ama, beni çok tüm bu yardımcı olmuyor. İşte biraz genişletilmiş örnektir:

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 

çıktısı: çok yararlı

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

değil. word ve number ile direct_speech öğesinin word? Etiketli olduğunu ayırt edemiyorum?!

Açıkçası bir şeyleri özlüyorum. Tüm yapmak istediğim: Bu farklı yaklaşıyor muyum?

cevap

1

peki, şimdi farklı bir dizi yaklaşım denedim ve ben, bu yüzden (görünmesine rağmen saçma) gerekenleri alamayan (Hoşgeldin Pyparsing kadar)

, ben .asXML() ve çözümleme kullanıyorum ortaya çıkan XML.

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

evlerin etrafında uzun bir yol gibi görünüyor, ama daha iyi bir yol olarak görünmüyor: çıkışı

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 

: İşte benim örnek.

5

r.sentence dizeleri ve ParseResults karışımını içerir ve yalnızca ParseResults desteği getName(). r.sentence üzerinden tekrar denemeyi denediniz mi? Ben asList() kullanarak çıktısını, ben alıyorum:

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

Ya da bu pasajı:

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

verir:

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

Ben sorunuza yanıt emin değilim, ama şimdi nereye gideceğine dair herhangi bir ışık tutuyor mu?