正则运算跟py语言的结合,知识点层出不穷
import re import time count ='1-2*((60-30+(-9-2*5/3+7/3*99/4*2998+10*568/14)*(-40/5))-(-4*3)/(16-3*2))' def atom_cal(atom_count):#计算乘除 for i in atom_count: if i == '*': n1,n2 = atom_count.split('*') return float(n1)*float(n2) elif i == '/': n1,n2 = atom_count.split('/') print(n1, n2) return float(n1)/float(n2) def atom_cal1(brack_ret):#计算加减 sum = 0 for i in brack_ret: # print('}}}}',brack_ret) # print(i) # time.sleep(3) # if i == '-': # if brack_ret.index(i) != 0: # print(brack_ret) # brack_ret = brack_ret.replace(i,',') # n1,n2 = brack_ret.split(',') # print('1111',n1,n2) # return float(n1)-float(n2) # elif i == '+': # n1,n2 = brack_ret.split('+') # print(n1,n2) # print(float(n1)+float(n2)) # return float(n1)+float(n2) #search加减匹配出来的字符串,容易出现负号跟减号的混乱,在split的时候把负整数的负号也分割了,
#所以我建议用findall 加分组括号,取出(其中有带负号的数)所有的数,
#在加减的时候只需要所有数叠加,省去了判断加减的步骤
#例['-9', '-3.3333333333333335', '173134.50000000003', '405.7142857142857']
sum += float(i)
return sum def dropbug(brack_ret): # 这个算是一个置换符号的操作 ,计算机无法,因为遇到这种两个运算符在两个数之间,
#在我们正则匹配的时候就容易出现错误,所以我们 brack_ret = brack_ret.replace('--', '+') # 最好将两个运算符变成一个,便于我们匹配跟计算 brack_ret = brack_ret.replace('-+', '-') brack_ret = brack_ret.replace('+-', '-')
brack_ret = brack_ret.replace('++', '+') return brack_ret def cal(brack_ret): while 1: brack_ret_count = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?',brack_ret) #在乘除匹配的时候,一个二元表达式前一个元,不要
#带-?,因为乘除算完了最终替换的时候会带上这个负号 if brack_ret_count: #第二个元必须带-?因为会影响到乘除的计算,要记住我们 atom_count = brack_ret_count.group() #索引的时候是从左到右的,计算表达式也是从左到右 atom_result = atom_cal(atom_count) brack_ret = brack_ret.replace(atom_count,str(atom_result)) else: break # print(brack_ret,type(brack_ret)) brack_ret = dropbug(brack_ret) # time.sleep(6) #在程序运行出来的时候,出现循环的时候,我们可以导入time模块,让代码运算速度慢下来,time.sleep(a) 括号里的参数a 是秒 print(brack_ret) #同时可以在你找到错误的地方附近的位置加一个print() 你随便打印什么都好分割代码运行,可以便于查bug brack_ret_3 = brack_ret # time.sleep(6) print('%%%%%%', brack_ret_3) brack_ret_2 = re.findall('(-?\d+(?:\.\d+)?)', brack_ret_3) if brack_ret_2: atom_count = brack_ret_2 # if brack_ret[1] == '-': # print('*****',atom_count,type(atom_count)) # atom_count = atom_count.insert(0,'-') print('+++++',atom_count,type(atom_count)) atom_result = atom_cal1(atom_count) print('^^^^^^^^^',atom_result) brack_ret_3 = str(atom_result) print(brack_ret_3) # print('----',brack_ret) return brack_ret_3 def main(count): while 1: ret = re.search('\([^()]+\)',count) print('0000',ret) if ret: brack_ret = ret.group() ret_1 = cal(brack_ret) count = count.replace(ret.group(),ret_1.strip('()')) # print(count) else: break return cal(count) result_2 = main(count) print(result_2) print(eval('1-2*((60-30+(-9-2*5/3+7/3*99/4*2998+10*568/14)*(-40/5))-(-4*3)/(16-3*2))')) #eval(): 字符串运算
知识点汇总:
匹配最里层括号: \([^()]\)
匹配在运算表达式字符串中带有负号的数(这个必须用分组括住,不然显示不正确):(-?\d+(?:\.\d+)?)
匹配乘除: \d+(\.\d+)?[*/]-?\d+(\.\d+)?
不要重复使用同一个变量名,容易搞混,要将变量名的描述描述清楚