2013-05-17 118 views
0

需要解析python中的命令輸出。該命令返回類似這樣Python解析複雜命令輸出

A: 
     2 bs found 
     3 cs found 
B: 
     1 a found 
     3 bs found 
C: 
     1 c found 
     D: 
       2 es found 
       3 fs found 

極品能夠做到與輸出如下:

訪問a.bs發現b.a發現。找到c.d.es等等。

我該如何做這個python?什麼數據結構最適合這樣做?

這個練習的目標是要運行的命令每10秒,並確定一個什麼樣的改變

+0

我該如何做一個代碼塊內的問題?我的命令的輸出格式都是錯位的。 – user2322491

+0

您可以選擇代碼塊可以按'ctrl + k'。 – satoru

+1

澄清 - 實際上是你的輸出的一部分,還是試圖使它成爲代碼塊? –

回答

0

這應該有一個「解析」的標籤,因爲它是一個一般的解析問題差異。

這種情況下的正常解決方案是跟蹤a)縮進和b)當前正在解析的結構列表,如同你在行中讀取的一樣。 b將以包含單個空字典的列表開始,即。 curparsing = [{}]

遍歷所有輸入行。例如:

with open('inputfilename','r') as f: 
    for line in f: 
     # code implementing the below rules. 
  • 如果行是空的(if not line.strip():),忽略它,去到下一個(continue

  • 如果縮進級別有所降低,我們應該去掉頂部當前解析列表中的項目(即curparsing.pop())。如果檢測到多個減少,我們應該從頂部刪除多個項目。

  • 去掉所有領先的壓痕與line=line.lstrip()

  • 如果「:」在該線路,那麼,我們已經找到了一個子字典。閱讀關鍵字(':'左側的部分),增加縮進級別,創建一個新字典,並將其插入列表當前頂部的字典中。然後將我們新創建的詞典附加到列表中。

  • if line[0] in '123456789':然後我們找到了'[count] [character] s found'的報告。 我們可以用正則表達式來找到計數和字符,用m = re.match('([1-9]+) ([a-z])'); count, character = m.groups(); count = int(count)。然後,我們將它存儲到當前列表的最上面的字典中:curparsing[-1][character] = count

就是這樣。您只需循環遍線並將這些規則應用於每行,最後,curparsing[0]包含解析的文檔。

+0

感謝您的指示。會試着讓你知道它是如何發生的 – user2322491

2

另一種解決方案是將輸入字符串直接轉換爲預先存在的庫可以讀取的內容。這個特定的數據看起來非常適合YAML。

在這種情況下,您應該使用re.sub('(+)([1-9]+) ([a-z]).+', '\\1\\3 : \\2', allcontent),它將'2 cs found'類型行重寫爲pyYAML能夠理解的鍵值映射。準確地說,'2 cs found'的格式變成'c:2'

結果?

A: 
     b : 2 
     c : 3 
B: 
     a : 1 
     b : 3 
C: 
     c : 1 
     D: 
       e : 2 
       f : 3 

執行yaml.load(newcontent)返回以下Python數據結構:

{'A': {'b': 2, 'c': 3}, 
'B': {'a': 1, 'b': 3}, 
'C': {'D': {'e': 2, 'f': 3}, 'c': 1}} 

其中我的建議,我先前的評論一致。 如果你更喜歡json(Python帶有一個json模塊),使用這個策略來生成JSON相當簡單。