python 分割和评估
我想把一个带后缀的字符串拆分成带括号的形式。我的意思是,如果用户输入了 3 (3 6 *) *
,我希望解释器能够把 3 18 *
进行相乘,并且能理解文本中的括号。这可能吗?就像 str.split()
,但是需要指定开始和结束的分隔符?
我是不是想得太天真了?我发现 shlex
模块有点类似,但我知道它只处理引号。
5 个回答
0
你可以写一个正则表达式来提取括号中的子表达式。如果你想要的是在匹配的括号上进行分割,re.split
可能会对你有帮助。一个简单的正则表达式可以让你挑选出这些子表达式。
#!/usr/bin/env python
import re
source = r"3 (3 6 *) *"
rewritten = source[:]
match_index = 1
snag_deepest = re.compile(r"""(?P<pre>.*)(?P<sub>\([^()]+\))(?P<post>.*)""")
print "Starting -> %s" % (rewritten)
results = snag_deepest.search(rewritten)
while results is not None:
print "Subexpression %d -> %s" % (match_index, results.group('sub'))
rewritten = "%s%s%s" % (results.group('pre'), "sub_%d" % match_index, results.group('post'))
print "Rewritten as -> %s" % (rewritten)
results = snag_deepest.search(rewritten)
match_index += 1
会产生
Starting -> 3 (3 6 *) *
Subexpression 1 -> (3 6 *)
Rewritten as -> 3 sub_1 *
1
我对正则表达式不是很熟悉。能不能给我一个例子呢?
正如Chris的各种评论所提到的,你不能用一个真正的正则表达式来解析嵌套的括号。(他说有一些黑科技和扩展可以让表达式语言解析上下文无关文法。这是我第一次听说,但我觉得这主意不太好。)
这个回答似乎也被投了反对票……还有其他方法吗?
可以看看这个链接。
3
我觉得使用 re
其实并不是个坏主意。你可以一个一个地处理嵌套的括号,把它们替换成运算的结果。对我来说,这看起来挺简单的:
import re
regex = re.compile(r'\([^\(\)]+\)')
def eval_expr(expr):
match = regex.search(expr)
if match:
sub_expr = match.group()
return eval_expr(expr.replace(sub_expr, str(eval_expr(sub_expr[1:-1]))))
args = expr.split()
op = args.pop()
return eval(op.join(args))
然后可以这样使用:
>>> eval_expr('(1 (2 3 -) 4 +) (5 6 *) 7 +')
<<< 41