2012-11-26 40 views
1

我有一些看起來像YAML但不是aint的數據。這是一個例子;解析空間縮進數據

An instance of A 
    objectID=123 
    family=abc 

An instance of A 
    objectID=234 
    family=bcd 
    List of 4 X elements: 
    An instance of X: 
     objectID=222 
     name=ccc 
    An instance of X: 
     objectID=333 

等等......

我需要找到一種方法,使之看起來更像是這樣的:

[ 
    {'name': 'An instance of A', 
    'data': [ 
    {'objectID': 123, 
     'family': 'abc' 
    } 
    ] 
}, 
... 

我試圖創造一些遞歸函數來分析這個,但它最終會變得一團糟。

我不是要求一個完整的工作示例,但在python中做到這一點的最佳方法是什麼? 自我調用功能?使用另一個庫(我還沒有找到)?使用另一種語言來幫助我,並將整個事件嵌入到Python中?

+0

您可以嘗試使用類似[pyparsing](http://pyparsing.wikispaces.com/)的庫。 – huon

回答

3

使用堆棧,並從中找到更多或更少的縮進級別;堆棧中的每個級別都包含縮進深度和條目:

stack = [(0, {})] # indentation level, top-level entry 
entry = stack[-1][1] 

for line in input: 
    line = line.strip() 
    if not line: continue 

    indentation = len(input) - len(input.lstrip()) 
    if indentation > stack[-1][0]: # indented further? New entry 
     entry = stack[-1][1]['data'] = {} 
     stack.append((indentation, entry)) # push 
    else: 
     while indentation < stack[-1][0]: # indentation dropped 
      del stack[-1]  # pop 
      entry = stack[-1][1] 

    # process line and add to entry 

result = stack[0][1] 
+0

當你到達以複合結尾的複合結束時,它將失敗:它只會從堆棧中彈出一個而不是兩個(或多個)。你需要像python那樣做,在那裏你保留一堆縮進並彈出堆棧,直到你點擊之前使用的縮進(或者報告一個錯誤,或者試圖猜測它們以前沒有使用過的新縮進的含義。 ) – rici

+0

@rici:當然,你需要在棧上包含縮進計數。更新我的答案,做到這一點,並彈出,直到縮進級別再次匹配。 –