文字列をリストの階層に変換する、再利用可能な優れたパーサーはありますか?

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

質問

次のような文字列を取得したい:

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

それをリストの階層に変換し、次のようなコードを実行した場合:

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

出力は次のようになります。

iii

これは、C#thisで記述されたいくつかの単純な解析コードが存在するのに十分な一般的な要件であることを望んでいます。

質問をより明確に表現できるかどうか教えてください。

役に立ちましたか?

解決

XMLまたは JSON は、このようなものを保存する優れた方法です。

スペンスが言ったように、これは難しい問題です。自分で転がすことはお勧めしません。

ほとんどの言語で実装する場合は、そのJSONリンクの一番下までスクロールします。

他のヒント

正規表現を使用する必要があります。部分文字列の一致と部分式を使用すると、sub-sub -...レベルを取得する再帰が得られます。

pregで/^\[(.+)\]$/などを使用して、単一レベルのアイテムを収集します。単一のシリーズの内臓を取得した後、レベルを受信しなくなるまで処理し、「」で爆発します。

「、」で結果を分割します。

次のように表示されるはずです

  • [One、Two [A、B [i、ii、iii、iv]、C]、Three]
    • 1つ
    • 2つ
    • [A、B [i、ii、iii、iv]、C]
      • A
      • B
      • [i、ii、iii、iv]
        • i
        • ii
        • iii
        • iv
      • C
    • 3つ

最後に左右のスペースを切り取り、洗練された結果を取得します。

配列またはリストの後ですか?

スペースを処理する必要があるため、文字列を使用するのは非常に困難です。または、要素でコンマを使用するなど。

このリストの内容を制御できる場合は、XMLまたはバイナリシリアル化を検討することをお勧めします。XMLまたはバイナリシリアル化には、これを支援するライブラリがあります。

これは実用的な答えではありませんが、.NET 4.0ベータ版を使用できる場合は、MicrosoftがテキストDSL用に開発しているOslo(およびその後のツール)を調べることができます。 / p>

また、フォーマットを制御する能力がある場合、私の投票はXMLまたはJSONまたは別のフォーマットに対するものです。しかし、それが欠けているので、私は退屈していたので、パーサーのPython実装があります。

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