2012-11-26 2 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' 
    } 
    ] 
}, 
... 

을, 그러나 그것은 엉망이되어 버린다.

완전한 작동 예제는 필요하지 않지만, 파이썬에서이 작업을 수행하는 가장 좋은 방법은 무엇입니까? 자체 호출 기능? 다른 lib (아직 찾지 못했던)를 사용하고 있습니까? 다른 언어를 사용하여 나를 돕고 모든 것을 파이썬에 포함 시키시겠습니까?

+0

당신은 [대한 파싱 (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

복합체로 끝나는 복합체의 끝 부분에 도달하면 실패합니다 : 두 개 (또는 그 이상) 대신 스택에서 한 가지만 팝합니다. 이전에 사용한 들여 쓰기를 히트 할 때까지 (또는 오류를보고하거나, 이전에 새로운 들여 쓰기가 사용되지 않았 으면 무엇을 의미했는지 추측하려고 시도 할 때까지) 당신은 들여 쓰기의 스택을 유지하고 스택을 팝하는 파이썬처럼 그것을 할 필요가 있습니다.) – rici

+0

@rici : 참, 스택에 들여 쓰기 수를 포함시켜야합니다. 들여 쓰기 수준이 다시 일치 할 때까지 내 대답을 업데이트했습니다. –