python写计算器
程序员文章站
2022-04-02 11:17:02
...
l = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
import re
def compute_mul_div(arg): # 计算乘除,接收列表[expression, 0]
val = arg[0] # 获取表达式
mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val) # 匹配乘法或除法
if not mch: # 如果没有乘法或除法 # 递归结束条件
return # 结束函数
content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val).group() # 寻找第一个乘法或除法
if len(content.split('*')) > 1: # 如是*
n1, n2 = content.split('*')
value = float(n1) * float(n2) # 计算乘法
else: # 如是/
n1, n2 = content.split('/')
value = float(n1) / float(n2) # 计算除法
before, after = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val, 1) # 等式用第一个乘法或除法分割成一个列表
new_str = "%s%s%s" % (before, value, after) # 替换原等式
arg[0] = new_str # 更改列表第一个元素
compute_mul_div(arg) # 继续执行该函数,直到没有乘法或除法
def compute_add_sub(arg): # 计算加减,参数为列表,第一个值为止含有加减法的等式,第二个值为0
while True:
if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__(
"--"): # 字符串中的 __contains__ 方法返回布尔值,判断参数是否在字符串中,如果等式含有以上4中之一,则替换
arg[0] = arg[0].replace('+-', '-')
arg[0] = arg[0].replace('++', '+')
arg[0] = arg[0].replace('-+', '-')
arg[0] = arg[0].replace('--', '+')
else: # 结束循环
break
if arg[0].startswith('-'): # 如果等式以-好开头
arg[1] += 1 # 列表中第二个值 + 1
arg[0] = arg[0].replace('-', '&')
arg[0] = arg[0].replace('+', '-')
arg[0] = arg[0].replace('&', '+')
arg[0] = arg[0][1:]
val = arg[0]
mch = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val) # 匹配加法或减法
if not mch: # 如没有 ,结束函数
return
content = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val).group() # 第一个加法或减法
if len(content.split('+')) > 1: # 如是加法
n1, n2 = content.split('+')
value = float(n1) + float(n2)
else: # 减法
n1, n2 = content.split('-')
value = float(n1) - float(n2)
before, after = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val, 1) # 等式以第一个加法或减法分开
new_str = "%s%s%s" % (before, value, after) # 更新等式
arg[0] = new_str # 更新列表
compute_add_sub(arg) # 继续执行该函数,直到变成一个数字
def compute(expression): # 先计算乘除,再计算加减
inp = [expression, 0] # 把无括号等式和0放入列表中
compute_mul_div(inp) # 把以上列表作为参数传给函数compute_mul_div,并执行该函数
compute_add_sub(inp)
if divmod(inp[1], 2)[1] == 1:
result = float(inp[0])
result = result * -1
else:
result = float(inp[0])
return result
def exec_bracket(expression): # 参数为没有空格的等式
'''
计算括号内的等式
'''
if not re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression): # 匹配最内侧括号,如为空 # 递归结束条件
final = compute(expression)
return final # 则结束此函数并执行compute函数
content = re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression).group() # 如有括号,获取第一个括号中内容
before, nothing, after = re.split('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expression, 1)
print('before:', expression)
content = content[1:len(content) - 1] # 获取除了括号中的内容
ret = compute(content) # 计算括号中等式
print('%s=%s' % (content, ret)) # 括号中等式 = 计算结果
expression = "%s%s%s" % (before, ret, after) # 重新赋值expression,计算结果代替了括号
print('after:', expression) # 替代后的表达式
print("=" * 10, '上一次计算结束', "=" * 10)
return exec_bracket(expression) # 第一个括号消除,继续消除第二个括号,知道原等式中没有括号,就执行compute函数
if __name__ == "__main__": # 运行程序
inpp = "1-2*((60-30 +(-40/5 )*(9-2*5/3+7/3*99 /4*2998+10*568/14))-(-4*3)/(16-3*2))"
inpp = re.sub('\s*', '', inpp) # 把inpp中的空白符替换成空字符
result = exec_bracket(inpp)
print(result)
正则表达式匹配括号