正則表達式實現計算器


#_author:來童星
#date:2019/11/10
import re
source='1-2 * ((60-30+(-40 / 5) * (9-2 * 5 / 3+ 7/3 * 99/4 *2998+10*568/14))-(-4*3)/(16-3*2))'
#做檢查
def check(s):
flag=True
if re.findall('[a-zA-Z]',source):#if re.findall('[a-z]',s.lower()):
print('表達式錯誤,包含非法字符')
flag=False
if not s.count('(')==s.count(')'):
print('表達式錯誤,括號未閉合')
flag=False
return flag
#做格式化處理
def format(s):
s=s.replace(' ','')
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(s):#(2+0.5*3.9)
# 從字符串中獲取一個乘法或除法的表達式
regular='[\-]?\d+\.?\d* [*/] [\-]?\d+\.?\d*'
#(30+6*2+9/3)
#如果還能找到乘或除法表達式
while re.search(regular,s):# 或者re.findall()都可以
# 獲取表達式
express=re.search(regular,s).group()# (1)6*2 (2) 9/3
#檢測是乘法還是除法
if express.count('*')==1 :
#獲取要計算的兩個數
x, y = express.split('*')
#計算結果
mul_result=str(float(x) * float(y))
#將計算的表達式替換為計算結果值
s=s.replace(express,mul_result)# s=(30+12+9/3)
#格式化
s = format(s)
#如果是除法
if express.count('/'):
# 獲取要計算的兩個數
x, y = express.split('/')
# 計算結果
div_result = str(float(x) / float(y))
s=s.replace(express, div_result)# s=(30+12+3)
s=format(s)
return s # s=(30+12+3)

def cal_add_sub(s):#(30+12-23+24-3)
regular_add='[\-]?\d+\.?\d* + [\-]?\d+\.?\d*'
regular_sub='[\-]?\d+\.?\d* - [\-]?\d+\.?\d*'
#開始加法,一定要加上while循環,如果不加只能處理一次
while re.findall(regular_add,s):
#把所有的加法都算完,獲取所有加法表達式
add_list=re.findall(regular_add,s)
for add_str in add_list:
#獲取兩個加法的數
x, y = add_str.split('+')
add_result='+'+str(float(x)+float(y))
s=s.replace(add_str,add_result)
s=format(s)
# 開始減法
while re.findall(regular_sub, s):
# 把所有的減法都算完,獲取所有減法表達式
sub_list = re.findall(regular_sub, s)
for sub_str in sub_list:
numbers=sub_str.split('-')
#-3-5的情況split會返回3個值
if len(numbers)==3:
result=0
for v in numbers: # 例如是-3-5 通過- 分為[] 3 5,
if v:# 如果3在number中,
result-=float(v) #則3變為-3,然后5進來,result=-3-5=-8
str(result) ##加了str()將結果轉化為字符串
else:
x,y=numbers
result=str(float(x)-float(y))##加了str()將結果轉化為字符串
#替換字符串
s = s.replace(sub_str,'+' + result) # +不是連接兩種數據類型相同的嗎???
s = format(s)
# 獲取兩個減法的數
# x, y = sub_str.split('-')
# sub_result = '+' + str(float(x) + float(y))
# s = s.replace(sub_str, sub_result)
# s = format(s)
#
# x,y=ret1.split('[*/]',ret1)
# #檢測是加法還是減法
# if '+' in ret1:
# ret2=float(x)+float(y)
# str(ret2)
# s.replace(ret1,ret2)
# else:
# ret2=float(x)-float(y)
# str(ret2)
# s.replace(ret1,ret2)
#
# return s#(17)

if check(source):
print('source',source)
print('eval result',eval(source))
strs=format(source)
print('source', source)

# 處理帶括號的
while source.count('(')>0:# re.search('\(')
#去括號,得到括號的字符串,結果如(30+6/3)
strs=re.search('\([^()]*\)',source).group()
#將括號的表達式進行乘除運算
replace_strs=cal_mul_div(strs)
# 將括號的表達式進行加減運算
replace_strs=cal_add_sub(replace_strs) # '(17)'
#將括號的字符串替換為計算結果,結果包含(),替換時去掉():[1:-1]
source=format(source.replace(strs,replace_strs[1:-1]))

#處理不帶括號的,沒有括號就到最后單一表達式了
else:
replace_strs = cal_mul_div(source)
replace_strs = cal_add_sub(replace_strs)
print('my result',source.replace('+',''))




免責聲明!

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



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