문자열을 목록의 계층으로 변환하는 좋은 재사용 가능한 구문 분석기가 있습니까?

StackOverflow https://stackoverflow.com/questions/456259

문제

다음과 같은 문자열을 가져 가고 싶습니다.

[One, Two[A, B[i, ii, iii, iv], C], Three]

다음과 같은 코드를 실행하는 경우 목록의 계층으로 변환하십시오.

Console.Write(myList[1][1][2]);

출력은 다음과 같습니다.

iii

나는 이것이 C#에 작성된 간단한 구문 분석 코드가 있다는 충분한 요구 사항이기를 바라고 있습니다.

내 질문이 더 명확하게 표현 될 수 있는지 알려주세요.

도움이 되었습니까?

해결책

XML 또는 JSON 이와 같은 것을 저장하는 훌륭한 방법입니다.

Spence가 말했듯이, 이것은 어려운 문제입니다. 나는 당신 자신을 굴리는 것을 권장하지 않습니다.

대부분의 언어로 구현하려면 JSON 링크의 하단으로 스크롤하십시오.

다른 팁

나는 정규 표현으로 가야했다. 서브 스트링 매치 및 하위 표현은 하위 서브 -... 레벨을 얻기위한 재귀를 줄 수 있습니다.

preg에서 /^ [(.+) /와 같은 것을 사용하여 단일 레벨의 항목을 수집하십시오. 더 이상 레벨을받지 못할 때까지 처리하고, '단일 시리즈의 용기를 얻은 후에', ',', ',', ',', ',', ',', ',', ',', ',', ',', ',', ',', ',', ',', ',', ',', ','단일 시리즈의 용기를 얻은 후에 더 이상 폭발하십시오.

a ','로 분할 결과.

처럼 나와야합니다

  • 하나, 2 개의 [A, B [I, II, III, IV], C], Three
    • 하나
    • A, B [I, II, III, IV], C
      • I, II, III, IV
        • II
        • III
        • IV

마지막으로 왼쪽/오른쪽 공간을 다듬어 세련된 결과를 얻으십시오.

배열 또는 목록 후에 있습니까?

이것은 공간을 다루거나 요소에 쉼표를 사용하기 때문에 문자열과 관련이 매우 어렵습니다.

이 목록에 무엇이 있는지에 대한 제어가 있다면 XML 또는 이진 직렬화를 조사하는 것이 좋습니다.

실용적인 답은 아니지만 .NET 4.0 베타를 사용할 수 있다면 Microsoft가 텍스트 DSL을 위해 개발하는 Oslo (및 후속 툴링)를 살펴볼 수 있습니다. 정확히 필요한 것 같습니다.

내 투표는 형식을 제어 할 수있는 XML 또는 JSON 또는 다른 형식에 대한 투표입니다. 그러나 그 부족은 여기에 지루했기 때문에 파서의 파이썬 구현이 있습니다.

class ExprParser(object):
current = []
list_stack = []

def __init__(self):
    pass

def parse(self,input):
    for atom in [s.strip() for s in input.split(',')]:
        self.parse_atom(atom)
    return self.current

def do_pushes(self,atom):
    """ Strip off the '[' and push new lists """
    i = 0
    while i < len(atom) and atom[i] == '[':
        self.push()
        i += 1
    return atom[i:]

def do_pops(self,atom):
    """ Pop the lists """
    i = 0
    while i < len(atom) and atom[i] == ']':
        self.pop()
        i += 1

def parse_atom(self,atom):
    push_start = atom.find('[')

    rest = self.do_pushes(atom[push_start:]) if push_start >= 0 else atom

    pop_start = rest.find(']')

    val = rest[:pop_start] if pop_start >= 0 else rest

    self.add(val)

    if pop_start >= 0:
        self.do_pops(rest[pop_start:])

def push(self):
    self.current = []
    self.list_stack.append(self.current)

def pop(self):
    done = self.list_stack.pop()
    self.current = self.list_stack[-1] if self.list_stack else done
    if self.current is not done:
        self.add(done)

def add(self,val):
    self.current.append(val)

사용 :

parser = ExprParser()
parser.parse('[One, Two[A, B[i, ii, iii, iv], C], Three]')

오류 입력에 대한 오류 처리는 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top