jus*_*ess 14 python parsing parentheses
显然,这个问题在阅读之后会经常出现
并且思考了一会儿的问题,我写了一个函数来返回包含在任意数量的嵌套()内的内容
该函数可以很容易地扩展到任何正则表达式对象,在此发布您的想法和注意事项.
任何重构建议将不胜感激
(注意,我仍然是python的新手,并且不想弄清楚如何引发异常或其他什么,所以我只是让函数返回'失败',如果它不能弄清楚发生了什么)
编辑功能以考虑评论:
def ParseNestedParen(string, level):
"""
Return string contained in nested (), indexing i = level
"""
CountLeft = len(re.findall("\(", string))
CountRight = len(re.findall("\)", string))
if CountLeft == CountRight:
LeftRightIndex = [x for x in zip(
[Left.start()+1 for Left in re.finditer('\(', string)],
reversed([Right.start() for Right in re.finditer('\)', string)]))]
elif CountLeft > CountRight:
return ParseNestedParen(string + ')', level)
elif CountLeft < CountRight:
return ParseNestedParen('(' + string, level)
return string[LeftRightIndex[level][0]:LeftRightIndex[level][1]]
Run Code Online (Sandbox Code Playgroud)
Gar*_*ees 29
您没有明确说明您的函数的规范是什么,但这种行为对我来说似乎是错误的:
>>> ParseNestedParen('(a)(b)(c)', 0)
['a)(b)(c']
>>> nested_paren.ParseNestedParen('(a)(b)(c)', 1)
['b']
>>> nested_paren.ParseNestedParen('(a)(b)(c)', 2)
['']
Run Code Online (Sandbox Code Playgroud)
您对代码的其他评论:
fail
?re.findall
,然后丢弃结果是浪费.Run Code Online (Sandbox Code Playgroud)>>> ParseNestedParen(')' * 1000, 1) RuntimeError: maximum recursion depth exceeded while calling a Python object
正如托米在你提到的问题中所说的那样,"正则表达式确实是错误的工具!"
解析嵌套表达式的常用方法是使用堆栈,沿着这些行:
def parenthetic_contents(string):
"""Generate parenthesized contents in string as pairs (level, contents)."""
stack = []
for i, c in enumerate(string):
if c == '(':
stack.append(i)
elif c == ')' and stack:
start = stack.pop()
yield (len(stack), string[start + 1: i])
>>> list(parenthetic_contents('(a(b(c)(d)e)(f)g)'))
[(2, 'c'), (2, 'd'), (1, 'b(c)(d)e'), (1, 'f'), (0, 'a(b(c)(d)e)(f)g')]
Run Code Online (Sandbox Code Playgroud)
括号匹配需要具有下推自动机的解析器。存在一些库,但是规则很简单,我们可以从头开始编写它:
def push(obj, l, depth):
while depth:
l = l[-1]
depth -= 1
l.append(obj)
def parse_parentheses(s):
groups = []
depth = 0
try:
for char in s:
if char == '(':
push([], groups, depth)
depth += 1
elif char == ')':
depth -= 1
else:
push(char, groups, depth)
except IndexError:
raise ValueError('Parentheses mismatch')
if depth > 0:
raise ValueError('Parentheses mismatch')
else:
return groups
print(parse_parentheses('a(b(cd)f)')) # ['a', ['b', ['c', 'd'], 'f']]
Run Code Online (Sandbox Code Playgroud)