计算器(正则表达式)

1.自己写的,当时没弄明白的点是float(字符串负号加数字) =负数本身

s = '1-2*((60-30 +(9-2*5/3+7/3*99/4*2998+10*568/14)*(-40 / 5))-(-4*3)/(16-3*2))'
s = s.replace(" ", "")
brackets_first = re.compile('\([^()]+\)')  # 找出最内层函数的内容
brackets_second = re.compile('\d+(?:\.\d+)?[*/]-?\d+(?:\.\d+)?')  # 把乘除的前后式子取出来
brackets_four = re.compile('\d+(?:\.\d+)?[-+]+-?\d+(?:\.\d+)?')  # 把加减的前后式子取出来
brackets_three = re.compile('\d+(?:\.\d+)?|[-+*/]')  # 把数字和符号分别取出
brackets_five = re.compile('-?\d+(?:\.\d+)?')
obj = sys.modules[__name__]
count_dict = {'+': 'add', '-': 'sub', '*': 'mul', '/': 'division'}
# 加减乘除的四个调用函数
def add(number1, number2):
	return str(float(number1) + float(number2))
def sub(number1, number2):
	return str(float(number1) - float(number2))
def mul(number1, number2):
	return str(float(number1) * float(number2))
def division(number1, number2):
	return str(float(number1) / float(number2))
def leijia(obj):
	if re.search('[+][+]', obj) != None:
		obj = re.sub('[+][+]', '+', obj)
	elif re.search('[+][-]', obj) != None:
		obj = re.sub('[+][-]', '-', obj)
	elif re.search('[-][+]', obj) != None:
		obj = re.sub('[-][+]', '-', obj)
	elif re.search('[-][-]', obj) != None:
		obj = re.sub('[-][-]', '+', obj)
	return obj

def double(obj):
	obj, number1 = re.subn('[*][-]', '*', obj)
	obj, number2 = re.subn('[/][-]', '/', obj)
	return obj, number1 + number2

while 1:
	if brackets_first.search(s) != None:
		count_number = 0
		result_frist = brackets_first.search(s).group()
		while 1:
			if brackets_second.search(result_frist) != None:
				result_second = brackets_second.search(result_frist).group()
				result_second, count = double(result_second)
				count_number += count

				result_three = brackets_three.findall(result_second)
				ret = getattr(obj, count_dict[result_three[1]])(result_three[0], result_three[2])
				if count % 2 != 0:
					ret = '-' + ret
				result_frist = brackets_second.sub(ret, result_frist, 1)
			elif brackets_four.search(result_frist) != None:
				result_second = brackets_four.search(result_frist).group()
				print(result_second)
				result_second = leijia(result_second)
				result_three = brackets_three.findall(result_second)
				ret = getattr(obj, count_dict[result_three[1]])(result_three[0], result_three[2])
				result_frist = brackets_four.sub(ret, result_frist, 1)
			else:
				result_frist = brackets_five.search(result_frist).group()
				break
		s = brackets_first.sub(result_frist, s, 1)
	else:
		break
print('About result:%s' % s)



#输出结果:About result:1-2*-1388338.2476190478
  • 很明显这段代码的运算结果不对,一是因为没有对括号外的数进行处理,二是没有/*那种处理不对

2.优化后的版本

from functools import reduce

#拿到字符串先进行取到括号里的内容
brackets_regular = re.compile('\([^()]+\)')
muldiv_regular = re.compile('\d+(\.\d+)?[*/]-?\d+(\.\d+)?')		#判断乘除式子
addsun_regular = re.compile('[-+]?\d+(?:\.\d+)?')

def cal_atomexp(atom_exp):
    # 计算乘除法
    if '*' in atom_exp:
        a, b = atom_exp.split('*')
        return str(float(a) * float(b))
    elif '/' in atom_exp:
        a, b = atom_exp.split('/')
        return str(float(a) / float(b))


#计算括号里的所有乘除的算式
def mulDiv(inner_bracket):
	while 1:
		inner_first = muldiv_regular.search(inner_bracket)
		#如果没有了乘除式子,就会得到None,那not None就为真跳出循环,
		#思想点::多利用上一层的值,然后not变为true或false
		if not inner_first: break
		aut_exp = inner_first.group()

		#对取到的算式切割取数字运算,但数字是字符串类型,要用float强转为float类型
		#负数也能通过数据类型强转进行转换
		atom_res = cal_atomexp(aut_exp)
		#运算过后进行赋值,这里应该给谁赋值,因为是inner_bracket在参与循环
		#inner_bracket = (9-10.0/3+7/3*99/4*2998+10*568/14)
		inner_bracket = inner_bracket.replace(aut_exp,str(atom_res))
	return inner_bracket

#计算所有括号里的加减算式
#字符串中的减号经过float类型强转过后就变成了负数,加号转为正数
#再把所有取出来的正负数全部进行相加操作
def addSub(inner_bracket):
	inner_first = addsun_regular.findall(inner_bracket)
	return str(reduce(lambda x,y:float(x)+float(y),inner_first))

#在做加减操作的时候,有必要先处理两个运算符连着的情况
def format_exp(exp):
    # 给表达式做格式化
    exp = exp.replace('--','+')
    exp = exp.replace('+-','-')
    exp = exp.replace('++','+')
    exp = exp.replace('-+','-')
    return exp

def cal_bracket(exp):	 #对每次取出的括号里的内容进行处理
	exp = mulDiv(exp)
	exp = format_exp(exp)
	return addSub(exp)

def main(s):				#主函数处理原算式
	s = s.replace(' ','')
	while 1:
		mata_regular = brackets_regular.search(s)
		if not mata_regular:break #如果没有括号了,退出循环
		mata_regular = mata_regular.group()
		ret = cal_bracket(mata_regular)
		s = s.replace(mata_regular,ret)		#再s算式中将取出括号的内容替换成运算过后的字符串类型的结果
	return cal_bracket(s)		#计算括号外的加减乘除运算


s1 = '1-2*((60-30 +(9-2*5/3+7/3*99/4*2998+10*568/14)*(-40 / 5))-(-4*3)/(16-3*2))'
print(main(s1))
print(eval(s1))
#输出结果
2776672.6952380957
2776672.6952380957

猜你喜欢

转载自blog.csdn.net/hgdl_sanren/article/details/81710414