1. Compact limit
import re, functools def cal(formula): while re.search('(?:\d+\.?\d+|\d+)[+\-*/]', formula): while re.search('[*/]', formula): formula = re.sub('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', str(functools.reduce(lambda i, j: float(i) * float(j), re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group().split('*')) if '*' in re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group() else functools.reduce(lambda i, j: float(i) / float(j), re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group().split('/'))), formula, 1) if re.search('(?:\d+\.?\d+|\d+)[+\-]', formula): formula = re.sub('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', str(functools.reduce(lambda i, j: float(i) + float(j), re.search('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group().rsplit('+', 1)) if '+' in re.search('(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group() else functools.reduce(lambda i, j: float(i) - float(j), re.search('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group().rsplit('-', 1))), formula, 1) return formula formula = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))' while re.search('\([^\(\)]+\)', formula): formula = re.sub('\([^\(\)]+\)', cal(re.search('\([^\(\)]+\)', re.sub('\s', '', formula)).group()).strip('()'), formula, 1) while re.search('[+\-*/]-', formula): formula = re.sub('[+]-', '-', formula) if '+-' in formula else re.sub('--', '', formula) if formula.startswith('--') else re.sub('(?:\d+\.?\d+|\d+)[*/]-', '-' + re.findall('(?:\d+\.?\d+|\d+)[*/](?=-)', formula)[0], formula) if re.search('[*/]-', formula) else re.sub('--', '+', formula) print(cal(formula).split('.0')[0] if cal(formula).endswith('.0') else cal(formula))
2. Full version
import re from functools import reduce def plus_minus(formula): ''' Calculation of addition and subtraction without brackets formula : Param formula: Wait calculated string with only addition and subtraction : Return: string calculation result '' ' P1 = re.compile ( ' - (: \ d + \ \ d + | \ d +) [+ \ -] (:??.??.? \ D + \ \ d + | \ d +) ' ) # match time subtraction the while the re.search (P1, Formula): # calculated each time a binary addition and subtraction, and to replace the original string, until the end of the calculation and calculates the number of all x = re.search (p1, formula) .group () # matched one calculation, addition and subtraction is determined, and then reduce the two numbers to the divided anonymous function to calculate. = the re.sub Formula (P1, STR (the reduce ( the lambda I, J: a float (I) + a float (J), x.rsplit ( ' + ' ,. 1)) IF ' + ' in X the else the reduce ( the lambda I, J: a float (I) - a float (J), x.rsplit ( ' -' ,. 1))), Formula,. 1 ) return Formula # PS. Subtraction calculation of multiplication and division can be used in different ways, all numbers can be calculated from the match-up again with def multi_divi(formula): ''' Formula without computation is in brackets : Param formula: Wait calculated string with only multiplication and division : Return: string calculation result ''' p = re.compile('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)') while re.search(p, formula): y = re.search(p, formula).group() formula = re.sub(p, str(reduce(lambda i, j: float(i) * float(j), y.split('*')) if '*' in y else reduce(lambda i, j: float(i) / float(j), y.split('/'))), formula, 1) return formula def parentheses_parse(formula): ''' Brackets for processing, and call completion of addition, subtraction calculation : Param formula: math formula string, addition, subtraction and support brackets : Return: the final result of integer or floating point ''' formula = re.sub('\s', '', formula) P = the re.compile ( ' \ ([^ \ (\)] + \) ' ) # match the inner bracket the while the re.search (P, Formula): # cycles to date no parentheses F = the re.search (P, formula) .group () Formula = the re.sub (P, plus_minus (multi_divi (F)). Strip ( ' () ' ), Formula,. 1) # call subtraction nested multiplication and division, the end of the calculation equation parentheses, brackets and removed # Handling of other connected with the negative sign may occur after removal of the brackets the while the re.search ( ' [+ \ - * /] - ' , Formula): formula = re.sub('[+]-', '-', formula) Formula = the re.sub ( ' - ' , '' , Formula) IF formula.startswith ( ' - ' ) the else the re.sub ( ' - ' , ' + ' , Formula) # negative negative negative negative It is positive, and to avoid a positive number appears in the forefront IF the re.search ( ' [* /] - ' , Formula): # encountered where multiplication and division are connected to a negative number, need to first pre-negative, once again above Modified minus connection process n-the re.search = ( ' (:?.?? \ D + \ \ + D | \ + D) [* /] (= -) ' , Formula) .group () # As used herein, a forward the obtained pre-matching '7 * -' such sequence '7 * portion apos Formula = the re.sub ( ' (:?.? \ D + \ \ D + | \ D +) [* /] - ' , ' - ' + n-, Formula) # string using the newly acquired replacement, to make '7 * - 'to' * -7 'look Formula = plus_minus (multi_divi (Formula)) # no parenthesis, and then calculating the final IF formula.endswith ( ' .0 ' ): # optimize the display formula = int (formula. Split ( ' .0 ' ) [0]) the else : formula = float(formula) return formula # Enter here formula Print (parentheses_parse ( ' 1-2 * ((30 + 60- (- 40/5) * (. 5 * -2. 9 /. 7. 3 + / 99. 3 * / 0. 1. 4 * + 2998 * 568/14)) - (- 4 * 3) / (16-3 * 2)) ' ))
3. clear thinking edition
import re from functools import reduce def mul_div(exp): """ Multiplication, or division of two numbers :param exp: :return: """ if '*' in exp: a, b = exp.split('*') return float(a)*float(b) if '/' in exp: a, b = exp.split('/') return float(a) / float(b) def exp_fmt(exp): """ Symbol finishing :param exp: :return: """ while re.search('[+-]{2,}',exp): exp = exp.replace('--','+') exp = exp.replace('+-','-') exp = exp.replace('-+','-') exp = exp.replace('++','+') return exp def remove_addsub(exp): """ Calculation of addition and subtraction of two numbers :param exp: :return: """ ret = re.findall('[-+]?\d+(?:\.\d+)?',exp) res = reduce(lambda a,b:float(a)+float(b),ret) return res def remove_muldiv(exp): """ All the calculation expression of multiplication and division :param exp: :return: """ while True: ret = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?',exp) if ret: son_exp = ret.group() res = mul_div(son_exp) exp = exp.replace(son_exp,str(res)) else:return exp def cal(exp): RES = remove_muldiv (exp) # computation is in RES = exp_fmt (RES) # sign finishing RET = remove_addsub (RES) # calculating subtraction return RET def main(exp): exp = exp.replace(' ','') while True: ret = re.search('\([^()]+\)', exp) if ret: res = cal (ret.group ()) exp = exp.replace(ret.group(), str(res)) else: return cal(exp) exp = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' ret = main(exp) print(ret)
to be continued