2016-11-18 37 views
2

我有一個簡單的例子,我想解析2行數據。如何在PyParsing中從結果對象中檢索值列表?

In [1] from pyparsing import Word, nums, OneOrMore, Optional, Suppress, alphanums, LineEnd, LineStart 

     Float = Word(nums + '.' + '-') 
     Name = Word(alphanums) 
     Line = OneOrMore(Float)('data') + Suppress(Optional(';')) + Optional('%') + Optional(Name)('name') 

     Lines = OneOrMore(Line + LineEnd()) 

     string = ''' 1 10 0  T20 
      1 76 0 T76 
     ''' 
     result = Lines.parseString(string) 

In [2] result 
Out[2] (['1', '10', '0', 'T20', '\n', '1', '76', '0', 'T76', '\n'], {'data': [(['1', '10', '0'], {}), (['1', '76', '0'], {})], 'name': ['T20', 'T76']}) 

結果對象包含了所有我需要的值,即data值和name鍵與項目列表順序根據就行了。我如何從結果對象獲取值?

訪問數據屬性並沒有給兩行

In [3] result.data 
Out[3] (['1', '76', '0'], {}) 

In [4] for i in result.data: 
      print i 
     1 
     76 
     0 

asDict()方法只返回第二行

In [5]: result.asDict() 
Out[5]: {'data': ['1', '76', '0'], 'name': 'T76'} 

asList()方法返回一個列表中的所有信息,並且很難當你不知道namedata提前時間長度

In [6]: result.asList() 
Out[6]: ['1', '10', '0', 'T20', '\n', '1', '76', '0', 'T76', '\n'] 

asXML()包含我需要的所有內容,但它是XML格式,並且文檔字符串表示它將很快被棄用。

In [7]: print result.asXML() # The documentation says this will be deprecated 
     <data> 
      <data>1</data> 
      <ITEM>10</ITEM> 
      <ITEM>0</ITEM> 
      <name>T20</name> 
      <ITEM> 
     </ITEM> 
      <data>1</data> 
      <ITEM>76</ITEM> 
      <ITEM>0</ITEM> 
      <name>T76</name> 
      <ITEM> 
     </ITEM> 
     </data> 

dump()再次部分包含了相關信息,但它返回一個字符串,一個人必須要再次解析字符串信息。

In [8]: print result.dump() 
     ['1', '10', '0', 'T20', '\n', '1', '76', '0', 'T76', '\n'] 
     - data: ['1', '76', '0'] 
     - name: 'T76' 

如何以Pythonic方式獲取這些值?

回答

1

使用結果名稱做得很好,它們在訪問分析字段時非常有用。但是,這聽起來像你需要結構的層添加到您的解析器,使每一行都有自己的數據,名稱等,您可以做到這一點的只是重新定義爲行:

Lines = OneOrMore(Group(Line) + LineEnd().suppress()) 

現在,如果你打印(result.dump()),您將獲得:

[['1', '10', '0', 'T20'], ['1', '76', '0', 'T76']] 
[0]: 
    ['1', '10', '0', 'T20'] 
    - data: ['1', '10', '0'] 
    - name: 'T20' 
[1]: 
    ['1', '76', '0', 'T76'] 
    - data: ['1', '76', '0'] 
    - name: 'T76' 

轉儲()的輸出並不意味着要分析得到的值,它的目的是幫助您展示如何結構化值可以被檢索到。舉例來說,你可以這樣做:

print(result[1].data) 
print(result[1].name) 

,並得到

['1', '76', '0'] 
T76 

或:

for parsed_line in result: 
    print("{name}: {data}".format_map(parsed_line)) 

,並得到:

T20: ['1', '10', '0'] 
T76: ['1', '76', '0'] 
+1

哇感謝詳細的,非常有用的答案保羅。我真的很喜歡你不僅對所問的問題給出了一個很好的答案,而且總是設法潛入其中的一些附加花絮(我到目前爲止還不瞭解format_map):)再次感謝,並且在包裝上做得非常好! – kdheepak