我想拿一个像这样的字符串:
[One, Two[A, B[i, ii, iii, iv], C], Three]
并将其转换为列表层次结构,这样如果我执行以下代码:
Console.Write(myList[1][1][2]);
输出将是:
iii
我希望这是一个很普遍的要求,即用C#编写一些简单的解析代码。
如果我的问题可以更清楚地表达,请告诉我。
答案 0 :(得分:4)
答案 1 :(得分:2)
我必须使用正则表达式。子串匹配和子表达式可以为您提供递归以获取sub-sub -...级别。
在preg中使用类似/^\ [(+)\] $ /的内容来收集单个级别的项目。处理它直到你不再获得一个级别,在获得单个系列的内容之后爆炸','爆炸。
按','。
拆分结果应该像
一样出现最后修剪左/右空格以获得抛光效果。
答案 2 :(得分:0)
你是在追求数组还是列表?
这对于字符串来说非常困难,因为你必须处理空格,或者在元素中使用逗号等。
如果您可以控制此列表中的内容,我建议您查看XML或二进制序列化,其中包含可帮助您执行此操作的库。
答案 3 :(得分:0)
这不是一个实际的答案,但如果您能够使用.NET 4.0测试版,您可以查看Microsoft正在为文本DSL开发的Oslo(以及后续工具),这似乎正是您所需要的。< / p>
答案 4 :(得分:0)
如果您能够控制格式,我的投票也适用于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]')
虽然格式错误的输入没有错误处理。