2012-07-26 40 views
2

我已經寫在下面pyparsing一個簡單的解析器:通過pyparsing樹遍歷只產生唯一的項目?

import pyparsing as pp 

Token = pp.Word(pp.alphas)("Token") 
Modifier = pp.Word(pp.nums)("Modifier") 

Random = pp.Group(pp.Keyword("?") + pp.OneOrMore(Modifier))("Random") 
Phrase = pp.Group(Token + pp.OneOrMore(Modifier))("Phrase") 

Collection = pp.Group(pp.delimitedList(Phrase^Random, ","))("Collection") 

tree = Collection.parseString("hello 12 2, ? 1 2, word 4, ? 3 4, testing 5") 

然後我試着這樣做:

>>> for name, item in tree[0].items(): 
     print name, item 
Phrase ['testing', '5'] 
Random ['?', '3', '4'] 

...但由於某些原因,它只有最後PhraseRandom返回在樹中的項目。我怎樣才能得到他們所有的人?

(注:我也試着這樣做:

>>> for item in tree[0]: 
     print item 
['hello', '12', '2'] 
['?', '1', '2'] 
['word', '4'] 
['?', '3', '4'] 
['testing', '5'] 

...但你可以看到,它不返回的標記名稱,我需要我也想這樣做item.name,但這些。總是返回空字符串。)

如何迭代pyparsing樹並按順序獲取每個項目以及指定的名稱?

回答

3

ParseResults可以通過調用getName()得到他們的定義名稱:

>>> for f in tree[0]: print f.getName(), f.asList() 
... 
Phrase ['hello', '12', '2'] 
Random ['?', '1', '2'] 
Phrase ['word', '4'] 
Random ['?', '3', '4'] 
Phrase ['testing', '5'] 

您也可以恢復使用setResultsName並設置listAllMatches參數設置爲True。在版本1.5.6中,expr("name")快捷方式得到了增強,因此如果名稱以'*'結尾,那麼相當於expr.setResultsName("name", listAllMatches=True)。以下是通過設置此標誌如何改變輸出:

>>> Random = pp.Group(pp.Keyword("?") + pp.OneOrMore(Modifier))("Random*") 
>>> Phrase = pp.Group(Token + pp.OneOrMore(Modifier))("Phrase*") 
>>> Collection = pp.Group(pp.delimitedList(Phrase^Random, ","))("Collection") 
>>> tree = Collection.parseString("hello 12 2, ? 1 2, word 4, ? 3 4, testing 5") 
>>> print tree.dump() 
[[['hello', '12', '2'], ['?', '1', '2'], ['word', '4'], ['?', '3', '4'], ['testing', '5']]] 
- Collection: [['hello', '12', '2'], ['?', '1', '2'], ['word', '4'], ['?', '3', '4'], ['testing', '5']] 
    - Phrase: [['hello', '12', '2'], ['word', '4'], ['testing', '5']] 
    - Random: [['?', '1', '2'], ['?', '3', '4']]