python正则练习---计算器

1、实现加减乘除及拓号优先级解析
2、用户输入带有加减乘除小括号的复杂运算公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致
# -*- coding:utf-8 -*-
import re


def check(string): #检查是否有其他特殊字符字母,检查表达式合法性
    flag=True
    if re.findall('[a-z]',string.lower()):
        print('表达式错误,包含非法字符')
        flag=False
    if not string.count("(") == string.count(")"):
        print("表达式错误,括号未闭合")
        flag=False
    return flag

def format_string(s):  #格式化字符串 :去掉空格
    s=s.replace(' ','')
    s=s.replace('--','+')
    s=s.replace('++','+')
    s=s.replace('+-','-')
    s=s.replace('-+','-')
    s=s.replace('*+','*')
    s=s.replace('/+','/')
    return s

def cal_mul_div(string): #计算乘除,如(30+6*2+9/3)
    # ret1=re.search('\d+\.?\d*[*/]\d+\.?\d*',s) #匹配小数\d+\.?\d*,匹配乘或除[*/]
    regular='\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*'
    while re.search(regular,string):
        expression = re.search(regular,string).group() #获取表达式6*2
        if expression.count("*")==1: #如果是乘法
            x,y = expression.split("*") #获取要计算的2个数
            mul_result = str(float(x) * float(y))
            string = string.replace(expression,mul_result) #将计算的表达式替换为计算结果值
            string = format_string(string) #格式化
        if expression.count("/"): #如果是除法
            x,y = expression.split("/")
            div_result = str(float(x) / float(y))
            string = string.replace(expression,div_result)
            string = format_string(string)
        if expression.count("*")==2: #如果是乘方
            x,y=expression.split('**')
            pow_result=1
            for i in range(int(y)):
                pow_result*=int(x)
            string=string.replace(expression,str(pow_result))
            string=format_string(string)
    return string

def cal_add_sub(string): #计算加减
    # ret1 = re.search('\d+\.?\d*[+-]\d+\.?\d*', s)  # 匹配小数\d+\.?\d*,匹配加或减[+-]
    add_regular='[\-]?\d+\.?\d*\+[\-]?\d+\.?\d*'
    sub_regular='[\-]?\d+\.?\d*\-[\-]?\d+\.?\d*'
    while re.findall(add_regular,string): #加法
        add_list = re.findall(add_regular,string)
        for add_str in add_list:
            x,y = add_str.split("+")
            add_result = "+" + str(float(x) + float(y))
            string = string.replace(add_str, add_result)
        string = format_string(string)
    while re.findall(sub_regular,string): #减法
        sub_list = re.findall(sub_regular,string)
        for sub_str in sub_list:
            numbers = sub_str.split("-")
            if len(numbers) == 3:
                result = 0
                for v in numbers:
                    if v:
                        result -= float(v)
            else:
                x,y = numbers
                result = float(x) - float(y)
    return string

if __name__ == "__main__":
    # source = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
    source = '1-2*3+9/3-(1+1+(2-1)*1)'
    if check(source):
        print("source:",source)
        print("eval result:",eval(source))
        source=format_string(source)
        print(source)
        # while re.search('\('):
        while source.count('(') > 0:
            strs=re.search('\([^()]+\)',source).group()  #找到最里面的()
            repalce_str=cal_mul_div(strs) #将括号里面的表达式进行乘除运算(2+15)
            replace_str=cal_add_sub(repalce_str) #将括号里面的表达式进行加减运算 '(17)'
            source=format_string(source.replace(strs,repalce_str[1:-1])) #将括号的字符串替换为计算结果,结果包含(),替换时去掉():[1:-1]

        else: #没有括号就到最后单一表达式了
            strs = cal_mul_div(strs)  # 算乘除
            strs = cal_add_sub(strs)  # 算加减
            source = source.replace(source,replace_str)
        print("my result:",source.replace("+",""))


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值