下面是我自己花了一天时间,用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))
虽然在实际上没有什么用,不过锻炼锻炼脑子还是好的嘛!!!!!