<p>您可以使用<a href="https://en.wikipedia.org/wiki/Shunting-yard_algorithm" rel="nofollow noreferrer">Shunting-Yard</a>算法。然而,算法的完整实现是相当复杂的。这里有一个更简单,有点天真的版本,它可以给你一个基本的理解<a href="https://gist.github.com/tiabas/339f5c06f541c176a02c02cc3113d6f7" rel="nofollow noreferrer">https://gist.github.com/tiabas/339f5c06f541c176a02c02cc3113d6f7</a></p>
<pre><code># Simple Shunting-Yard solution
#
# Given a math expression, parse and evaluate
# the expression
#
# E.g '2+1' => 3, 8/2*4+1 => 17, 2+(1*2) = 4, ((2+4)/2*7) => 21
#
def parse_math_expression(exp):
PRECENDENCE = {
')': 3,
'(': 3,
'*': 1,
'/': 1,
'+': 0,
'-': 0,
}
output = []
operators = []
for ch in exp:
# Handle nested expressions
if ch == ')':
opr = operators.pop(0)
while opr != '(':
output.append(opr)
opr = operators.pop(0)
elif ch.isdigit():
output.append(ch)
else:
# Handle operator prescendence
top_op = None
if len(operators) and operators[0]:
top_op = operators[0]
# Check if top operator has greater prcendencethan current char
if top_op in ['*', '/'] and PRECENDENCE[top_op] > PRECENDENCE[ch]:
output.append(top_op)
operators.pop(0)
# Push operator onto queues
operators.insert(0, ch)
# Handle any leftover operators
while len(operators):
output.append(operators.pop(0))
return output
test1 = "(2+1)"
assert parse_math_expression(test1) == ['2', '1', '+']
test2 = "((2+4)/(2*7))"
assert parse_math_expression(test2) == ['2', '4', '+', '2', '7', '*', '/']
test3 = "(3*2)+(4/2)"
assert parse_math_expression(test3) == ['3', '2', '*','4', '2', '/','+']
def eval_parsed_expression(exp):
OPRS = {
'+': lambda a, b: a + b,
'-': lambda a, b: a - b,
'*': lambda a, b: a * b,
'/': lambda a, b: a / b
}
tmp = []
while len(exp) > 1:
k = exp.pop(0)
while not k in ['*', '-', '+', '/']:
tmp.insert(0, k)
k = exp.pop(0)
o = k
b = tmp.pop(0)
a = tmp.pop(0)
r = OPRS[o](int(a), int(b))
exp.insert(0, r)
return exp[0]
test4 = ['2', '1', '+'] # (2+1*2)
assert eval_parsed_expression(test4) == 3
test5 = ['2', '1', '2', '*', '+'] # (2+1*2)
assert eval_parsed_expression(test5) == 4
test6 = ['3', '2', '*','4', '2', '/','+'] # (3*2)+(4/2)
assert eval_parsed_expression(test6) == 8
</code></pre>