2013-05-20 2 views
5

Я только начал использовать pyparsing этим вечером, и я создал сложную грамматику, которая описывает некоторые источники, с которыми я работаю очень эффективно. Это было очень легко и очень мощно. Тем не менее, у меня проблемы с работой с ParsedResults. Мне нужно иметь возможность перебирать вложенные токены в том порядке, в котором они найдены, и я нахожу это немного расстраивающим. Я отведенной мою проблему простой случай:`pyparsing`: iterating over` 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. 

не слишком полезно. Я не могу отличить word и number, а элемент 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.Вот мой пример:

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 

, который выводит:

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

кажется долгий путь вокруг дома, но не кажется, что будет лучше.

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)

Смежные вопросы