1. 程式人生 > >python正則計算器

python正則計算器

com split 可能 val 校驗 替換 clas mil ria

下面是我自己花了一天時間,用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))

python正則計算器