python正则计算器

下面是我自己花了一天时间,用python写出的个简易正则计算器,也踩了许多坑,功能还不完善,有何宝贵建议,请多多指教!

import re

back_bracket = re.compile('\([^()]+\)')  # 取出最内层括号
back_on = re.compile('(\+?\-?\d+\.?\d*)')  # 匹配带正负号数字
back_wf = re.compile('(\d+\.?\d*)')  # 匹配数字
back_qb = re.compile('\((.*)\)')  # 去除外层括号
back_sy = re.compile('\d([\+\-\*\/])\-?\d')  # 取出运算符+-*/
back_sj = re.compile('\d([\+\-])\-?\d')  # 取出运算符+-
back_qx = re.compile('\-?\d+\.?\d*[\*\/]\-?\d+\.?\d*')  # 取出乘除优先
back_jj = re.compile('\+?\-?\d+\.?\d*')  # 取出加减
back_zm = re.compile('[^+\-*/\d.()]')  # 匹配非法字符


# 计算乘除
def re_b(str_b):
    if '*' in str_b:
        a1, a2 = str_b.split('*')
        return float(a1) * float(a2)
    if '/' in str_b:
        a1, a2 = str_b.split('/')
        return float(a1) / float(a2)


# 式子中可能有括号内的值算完带有正负号,与括号前的叠加在一起,替换之
def th(s):
    s = s.replace('-+', '-')
    s = s.replace('+-', '-')
    s = s.replace('++', '+')
    s = s.replace('--', '+')
    return s


# 按顺序+-*/
def jjcc(s):
    while back_qx.search(s):  # 循环计算*/
        list_xc = back_qx.findall(s)
        res = re_b(list_xc[0])  # 调用re_b进行乘除计算
        if float(res) > 0:
            res = '+' + str(res)
        s = s.replace(list_xc[0], str(res), 1)  # 替换一次,防止将后面相同的字符串被替换
        s = th(s)
    while back_sj.search(s):  # 循环计算+-
        list_jj = back_jj.findall(s)
        res = float(list_jj[0]) + float(list_jj[1])  # 所取值带有+-号,因此直接进行加减运算
        s = s.replace(list_jj[0] + list_jj[1], str(res), 1)
        s = th(s)
    return s


# 取出并计算括号中的值,并返回
def qch(s):
    while back_bracket.search(s):  # 循环计算所有括号
        ss = back_bracket.findall(s)
        str_b = back_qb.findall(ss[0])[0]  # 去外层括号
        str_b = jjcc(str_b)
        s = s.replace(ss[0], str_b)
        s = th(s)
    return s


# 去除式子中的空格和非法字符
def qcg(s):
    s = s.replace(' ', '')
    if back_zm.search(s):
        print(s)
        print('式中含有非法字符')
        exit()
    return s


def main(s):
    s = qcg(s)  # 校验算式
    s = qch(s)  # 先算括号
    s = jjcc(s)  # 在顺序执行加减乘除
    return s


if __name__ == '__main__':
    s = '1-2*((60-30 +(9-2*5/3+7/3*99/4*2998+10*568/14)*(-40 / 5))-(-4*3)/(16-3*2))'
    print('eval:', eval(s))
    print('calau:', main(s))

import re
back_bracket = re.compile('\([^()]+\)')  # 取出最内层括号back_on = re.compile('(\+?\-?\d+\.?\d*)')  # 匹配带正负号数字back_wf = re.compile('(\d+\.?\d*)')  # 匹配数字back_qb = re.compile('\((.*)\)')  # 去除外层括号back_sy = re.compile('\d([\+\-\*\/])\-?\d')  # 取出运算符+-*/back_sj = re.compile('\d([\+\-])\-?\d')  # 取出运算符+-back_qx = re.compile('\-?\d+\.?\d*[\*\/]\-?\d+\.?\d*')  # 取出乘除优先back_jj = re.compile('\+?\-?\d+\.?\d*')  # 取出加减back_zm = re.compile('[^+\-*/\d.()]')  # 匹配非法字符

# 计算乘除def re_b(str_b):    if '*' in str_b:        a1, a2 = str_b.split('*')        return float(a1) * float(a2)    if '/' in str_b:        a1, a2 = str_b.split('/')        return float(a1) / float(a2)

# 式子中可能有括号内的值算完带有正负号,与括号前的叠加在一起,替换之def th(s):    s = s.replace('-+', '-')    s = s.replace('+-', '-')    s = s.replace('++', '+')    s = s.replace('--', '+')    return s

# 按顺序+-*/def jjcc(s):    while back_qx.search(s):  # 循环计算*/        list_xc = back_qx.findall(s)        res = re_b(list_xc[0])  # 调用re_b进行乘除计算        if float(res) > 0:            res = '+' + str(res)        s = s.replace(list_xc[0], str(res), 1)  # 替换一次,防止将后面相同的字符串被替换        s = th(s)    while back_sj.search(s):  # 循环计算+-        list_jj = back_jj.findall(s)        res = float(list_jj[0]) + float(list_jj[1])  # 所取值带有+-号,因此直接进行加减运算        s = s.replace(list_jj[0] + list_jj[1], str(res), 1)        s = th(s)    return s

# 取出并计算括号中的值,并返回def qch(s):    while back_bracket.search(s):  # 循环计算所有括号        ss = back_bracket.findall(s)        str_b = back_qb.findall(ss[0])[0]  # 去外层括号        str_b = jjcc(str_b)        s = s.replace(ss[0], str_b)        s = th(s)    return s

# 去除式子中的空格和非法字符def qcg(s):    s = s.replace(' ', '')    if back_zm.search(s):        print(s)        print('式中含有非法字符')        exit()    return s

def main(s):    s = qcg(s)  # 校验算式    s = qch(s)  # 先算括号    s = jjcc(s)  # 在顺序执行加减乘除    return s

if __name__ == '__main__':    s = '1-2*((60-30 +(9-2*5/3+7/3*99/4*2998+10*568/14)*(-40 / 5))-(-4*3)/(16-3*2))'    print('eval:', eval(s))    print('calau:', main(s))

猜你喜欢

转载自www.cnblogs.com/gyk1030/p/10803941.html