文字列をリストの階層に変換する、再利用可能な優れたパーサーはありますか?
質問
次のような文字列を取得したい:
[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]')
不正な入力に対してはエラー処理は行われません。