python 分割和评估

1 投票
5 回答
1258 浏览
提问于 2025-04-16 19:30

我想把一个带后缀的字符串拆分成带括号的形式。我的意思是,如果用户输入了 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

撰写回答