正則表達式計算器


''
計算流程:
1.將括號表達式(內部不包含括號)匹配出來
2.計算括號表達式的值,用計算值替換原括號表達式
    計算處理流程:
    1)從左至右匹配,匹配出乘法或除法表達式,計算出值,塞回去替換匹配的內容
    2)乘除法運算都已處理完,對剩下表達式從左至右匹配
    3)匹配一個加法或減法運算式,計算出值,塞回去,替換匹配的表達式
    4)直到沒有匹配運算式,停止,本輪括號表達式計算替換值流程完成
3.再次進行括號表達式(內部不包含括號)匹配
4.重復2
5.直到匹配不出括號表達式,直接對剩余運算式進行乘除加減處理
'''
import re

p1 = re.compile(r'\+\s*?-|-\s*?\+')  # 匹配'+-或-+' 匹配-+是為了處理用戶輸入原始表達式中有-+的情況
p2 = re.compile(r'-\s*?-')  # 匹配'--'


def process_multi_divis(s):
    pattern = re.compile(r'-?\d+(?:\.?\d+)?\s*?[*/]{1}\s*?-?\s*?\d+(?:\.?\d+)?')  # 匹配 *,/,*-,/- 四種情況
    while 1:
        result_process_p1 = re.sub(p1, '-', s)
        s = re.sub(p2, '+', result_process_p1)
        r = re.search(pattern, s)
        if r:
            r = r.group()
            if '*' in r:
                a, b = r.split('*')
                result = float(a.strip()) * float(b.strip().replace(' ', ''))  # 5 *- 6這種表達式,去除負號與數字之間空格
            elif '/' in r:
                a, b = r.split('/')
                result = float(a.strip()) / float(b.strip().replace(' ', ''))
            s = s.replace(r, str(result))
        else:
            return s


def process_plus_reduce(s):
    pattern = re.compile(r'-?\d+(?:\.?\d+)?\s*?[+-]{1}\s*?\d+(?:\.?\d+)?')
    while 1:
        result_process_p1 = re.sub(p1, '-', s)
        s = re.sub(p2, '+', result_process_p1)
        r = re.search(pattern, s)
        if r:
            r = r.group()
            if '+' in r:
                a, b = r.split('+')
                result = float(a.strip()) + float(b.strip())
            elif '-' in r:
                if r.startswith('-'):  # 處理類似 -5-10 這種表達式
                    nums = r.split('-')
                    a, b = nums[1], nums[2]
                    result = - float(a.strip()) - float(b.strip())
                else:
                    a, b = r.split('-')
                    result = float(a.strip()) - float(b.strip())
            s = s.replace(r, str(result), 1)  # 只替換一次,避免遇到1+1+1+1這樣的表達式,發生多次替換的情況
        else:
            return s


def process_parentheses(s):
    pattern = re.compile(r'\([^(]+?\)')  # 匹配最內層括號
    while 1:
        r = re.findall(pattern, s)
        if r:
            for item in r:
                expression = item[1:-1]  # 去掉首尾括號
                r1 = process_multi_divis(expression)  # 處理乘除法
                r2 = process_plus_reduce(r1)  # 處理加減法
                s = s.replace(item, r2)  # 處理完成,替換計算結果后,表達式中可能會存在'+-','--'這種運算符,需匹配進行替換; '+-'替換為'-','--'替換為'+'
            result_process_p1 = re.sub(p1, '-', s)
            s = re.sub(p2, '+', result_process_p1)
        else:
            return s


def main():
    expression = input('請輸入要計算的表達式:')
    result_step1 = process_parentheses(expression)  # 處理括號
    result_step2 = process_multi_divis(result_step1)  # 計算乘除法
    final_result = process_plus_reduce(result_step2)  # 計算加減法
    print('計算結果:', final_result)


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

  第二版<><><><><>

import re

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

def cal_muldiv(inner_bracket):
while True: # 計算括號里的所有乘除法
# 匹配第一個乘除法 inner_bracket = (9-2*5/3+7/3*99/4*2998+10*568/14)
ret = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?', inner_bracket)
if not ret: break
atom_exp = ret.group() # 獲取乘除法表達式 # 2*5
atom_res = cal_atomexp(atom_exp) # 計算乘除法的函數,得到結果 10.0
inner_bracket = inner_bracket.replace(atom_exp, str(atom_res))
# inner_bracket = (9-10.0/3+7/3*99/4*2998+10*568/14)
# 將得到的結果與匹配到的表達式進行兌換
return inner_bracket # 返回的是一個純加減法組成的算式

def cal_addsub(inner_bracket):
# 計算括號中的所有加減法
# (9 - 3.3333333333333335 + 173134.50000000003 + 405.7142857142857)
ret_l = re.findall('[-+]?\d+(?:\.\d+)?', inner_bracket)
sum = 0
for i in ret_l:
sum += float(i)
return str(sum)

def format_exp(exp):
# 給表達式做格式化
exp = exp.replace('--','+')
exp = exp.replace('+-','-')
exp = exp.replace('++','+')
exp = exp.replace('-+','-')
return exp

def main(s):
s = s.replace(' ', '')
while True:
# 找最內層的小括號
inner_bracket = re.search('\([^()]+\)', s)
if not inner_bracket: break # 找不到小括號了就退出
inner_bracket = inner_bracket.group()
inner_bracket_bak = inner_bracket
inner_bracket = cal_muldiv(inner_bracket) # 括號內的 : 計算了所有乘除法,只剩下加減法的表達式
inner_bracket = format_exp(inner_bracket)
res = cal_addsub(inner_bracket)
s = s.replace(inner_bracket_bak, res)
s = cal_muldiv(s)
s = format_exp(s)
s = cal_addsub(s)
return s

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 = '3333 - 0.0000002 * ( (6-30 +(-222/5) * (9-2*5/3 + 7 /3*99/4*2222298 +10 * 1 )) - (-4*3)/ (5-3*2) )'
print(main(s))
print(eval(s))


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM