在Python中对代码块进行分词
我有这样一个字符串:
[a [a b] [c e f] d]
我想要一个像这样的列表:
lst[0] = "a"
lst[1] = "a b"
lst[2] = "c e f"
lst[3] = "d"
我现在的做法是用两个递归函数(一个是用'['来分割,另一个是用']'来分割),我觉得这样不太优雅,也不太符合Python的风格。不过我相信可以用列表推导式或者正则表达式来实现(但我还没找到一个合理的方法)。
有没有什么好的主意?
3 个回答
1
好吧,如果你要处理的是一种递归的数据结构,那你就需要一个递归的函数来方便地遍历它。
不过,Python确实有一个可以分词的库,这可能会对你有帮助:http://docs.python.org/library/tokenize.html
1
如果这是一个递归的数据结构,那么用递归的方法来遍历它是很合适的。不过,在解析字符串来创建这个结构时,并不一定需要用递归。另一种我会用的方法是迭代:
origString = "[a [a b] [c [x z] d e] f]".split(" ")
stack = []
for element in origString:
if element[0] == "[":
newLevel = [ element[1:] ]
stack.append(newLevel)
elif element[-1] == "]":
stack[-1].append(element[0:-1])
finished = stack.pop()
if len(stack) != 0:
stack[-1].append(finished)
else:
root = finished
else:
stack[-1].append(element)
print root
当然,这个方法可能还有改进的空间,而且它会创建一系列嵌套的列表,也就是列表里面还有列表,里面再有列表,最后是字符串,这并不是你例子中想要的那种结构。不过,它确实可以处理树的任意深度。
4
其实这并不是一个递归的数据结构,注意到 a
和 d
是在不同的列表里。你只是把字符串按照括号字符分开,并去掉了一些空格。
我相信有人能找到更简洁的方法,但如果你想要一行代码,下面这样的写法应该能接近你的需求:
parse_str = '[a [a b] [c e f] d]'
lst = [s.strip() for s in re.split('[\[\]]', parse_str) if s.strip()]
>>>lst
['a', 'a b', 'c e f', 'd']