Python全棧--6.1-match-search-findall-group(s)的區別以及計算器實例


match、search、findall、group(s) 區別

import re 
# match findall經常用 
# re.match() #從開頭匹配,沒有匹配到對象就返回NONE 
# re.search() #瀏覽全部字符,匹配第一個符合規則的字符串 
# re.findall() # 將匹配到的所有內容都放置在一個列表中 

一、match有兩種情況

-------  有分組 ------取匹配到的正則再次取其部分內容

origin = "hello alex sadf dsaf"
r = re.match("(h)\w+",origin) 
print(r.group())  # hello  獲取匹配所有結果 
print(r.groups())  #('h',)  #獲取模型中匹配到的分組 沒有分組則為空元組 
r = re.match("(?P<n1>h)(?P<n2>\w+)",origin)  #獲取模型中匹配到的分組中所有執行力key的組 ?P<KEY>VALUE   {'n2': 'ello', 'n1': 'h'} 
print(r.groupdict())   #?P<KEY>VALUE   {'n2': 'ello', 'n1': 'h'} 

-------  無分組 ------

r = re.match("h\w+",origin) 
print(r.group()) # 獲取匹配所有結果 hello 
print(r.groups()) #獲取模型中匹配到的分組 () 
print(r.groupdict())  #獲取模型中匹配到的分組 {} 

二、groups、group、groupdict

print(r.group())  # hello  獲取匹配所有結果 
print(r.groups())  #('h',)  #獲取模型中匹配到的分組 沒有分組則為空元組 
r = re.match("(?P<n1>h)(?P<n2>\w+)",origin)  #獲取模型中匹配到的分組中所有執行力key的組 ?P<KEY>VALUE   {'n2': 'ello', 'n1': 'h'} 
print(r.groupdict())   #?P<KEY>VALUE   {'n2': 'ello', 'n1': 'h'} 

三、search兩種情況

search 不用從開頭匹配,而是匹配全局整個字符串,一旦又符合就退出

-------  有分組 ------

origin = "hello alex alix bcd dsfa lefg abc 199"
r = re.search("a(\w+)",origin) 
print(r.group()) #alex 
print(r.groups()) #('lex',) 
r = re.search("(?P<key1>a)(?P<key2>(\w+))",origin) 
print(r.groupdict()) #{'key1': 'a', 'key2': 'lex'} 

-------  無分組 ------

origin = "hello alex alix bcd dsfa lefg abc 199"
r = re.search("ali\w+",origin) 
print(r.group()) #alix 
print(r.groups()) #() 
print(r.groupdict()) #{} 

四、findall

# 1 匹配到之后,就抽離,繼續從下一個字符開始匹配

origin = "a2b3c4d5"
a=re.findall("\d+\w\d+",origin)   #['2b3', '4d5'] 
print(a) 

# 2 空值也會挨個字符去匹配,結尾后,還要繼續多匹配一次

num = "asd"
print(re.findall("",num))  # ['', '', '', ''] 

# 無分組

origin = "hello alex alix bcd dsfa lefg abc 199"
print(re.findall("a\w+",origin)) # ['alex', 'alix', 'abc'] 
print(re.findall("(a\w+)",origin)) #['alex', 'alix', 'abc'] 
print(re.findall("a(\w+)",origin)) #組 groups ['lex', 'lix', 'bc'] 
print(re.findall("(a)(\w+)(x)",origin)) # [('a', 'le', 'x'), ('a', 'li', 'x')] 將 三個分組匹配到的做成元組 放到列表作為一個元素 

 

findall  的特點

 分組匹配 
    * 貪婪匹配: 比如如下的asd 為一個分組,而一旦遇到asd開始的字符串,如果 
后面還是asd也會匹配,這就是貪婪匹配。 
    findall 特性: 
        1 有幾個分組返回幾個內容:,並將返回內容放到元組內 作為列表的一個元素。 
        2 即盡管* 匹配到了兩個asd ,但是因為是貪婪虛擬匹配出的,有一個分組,所以, 
        只會,取一個。 
        3 而findall默認只取最后一組匹配的內容,故此 只返回最后一組asd 
        4 findall 如果正則能有空的匹配的話,那么匹配字符串最后還會匹配到一個空 
        5 多個分組匹配到做成元組,當成列表的一個元素 
        6 多個分組,查找順序,外到內,左到右 ((\w)(\w)){2,} 先是找到2個字母的,再在這兩個字母里面進行局部分組 

# 1 特性 1 2 3 4 

print(re.findall(r'(asd)*','asdasd'))  #['asd', ''] 

# 2 如下,默認+可以第一次 就匹配到 1asd2asd 但由於前面只有1個分組,只能返回后面的4位了

n = re.findall("(\dasd)+","1asd2asdp2asds") # ['2asd', '2asd'] 
print(n) 

# 3 如下,默認*可以第一次 就匹配到 1asd2asd 但由於前面只有1個分組,只能返回后面的4位了

  #但是*還可以表示0次,故再遇到p的時候,空就能匹配了,而且,最后還有個s也匹配到空,結尾還默認還會匹配到空

n = re.findall("(\dasd)*","1asd2asdp2asds") # ['2asd', '', '2asd', '', ''] 
print(n) 

#4 匹配,最多四個字母,因此alex都找到了,但是只有一個分組,所以只返回最后一個\w故x

a = "alex"
n = re.findall("(\w){4}",a) 
print(n)  # ['x'] 

#5 這里findall 匹配分組是一個字母匹配到了,而*是貪婪匹配,四個字母都匹配就取到了四個字母,而正則分組只有一個,因此只取最后一個

a = "alex"
n = re.findall("(\w)*",a) 
print(n)  # ['x', ''] 

#6 由於從外到內, 所以匹配兩個字母的 al 匹配到了,ex也匹配到了,外部分組1個,因此ex,而內部從左到右又會匹配。

a = "alex"
n = re.findall("((\w)(\w)){2,}",a) 
print(n)  # [('ex', 'e', 'x')] 

#7 會匹配ax alex alex acd 但是貪婪匹配的分組只有 1個 因此 ax ax ax ad

origin = "hello ax lex bed alex lge alex acd 19"
n = re.findall("(a)(\w)*" , origin) 
print(n)  #[('a', 'x'), ('a', 'x'), ('a', 'x'), ('a', 'd')] 

實例  Python編寫計算器

#!/usr/bin/env python 
# _*_ coding:utf-8 _*_ 

import re,time 
def compte_add_sub(inp): 
    arg = inp[0]  # 傳入的只剩下 加減的字符串為列表 獲取第一個值 
    if arg.find("+-") != -1 or arg.find("-+") != -1: 
        arg = arg.replace("+-","-",len(arg)) 
        arg = arg.replace("-+","-",len(arg)) 
    elif arg.find("++") != -1  or arg.find("--") != -1: 
        arg = arg.replace("++","+",len(arg)) 
        arg = arg.replace("--","+",len(arg)) 
    arg = re.findall("[\+\-]|\d+\.?\d*",arg) # 
    if arg[0] == "-": 
        arg[0]=arg[0]+arg[1] 
        del arg[1] 
    add_sum = float(arg[0]) 
    for i in range(1,len(arg),2): 
        if arg[i] == "+": 
            add_sum +=float(arg[i+1]) 
        elif arg[i] == "-": 
            add_sum -= float(arg[i+1]) 
    return add_sum 
#處理乘除 
def compute_mul_div(arg): 
    arg = arg[0] 
    end =len(arg) 
    ###########計算平方########## 
    arg = re.sub("(//)","/",arg) 
    #print(arg) 
    while True: 
        x = re.search("\d+\.*\d*(\*\*)\d+\.*\d*",arg) 
        if x: 
            expre = x.group() 
            print(expre) 
            x = x.group().split("**") 
            ret = float(x[0]) ** float(x[-1]) 
            if "e" in str(ret): 
                ret=int(ret) 
            #print(ret) 
            arg = arg.replace(expre,str(ret),1) 
            print(arg) 
        else: 
            #print("exit") 
            break
    ###########計算平方########## 
    li = re.findall(r"[*/]",arg) 
    num = len(li) 
    for i in range(num): 
        new = arg.split(li[i],1) 
        la=re.findall("[\+\-\/]?(\d+\.?\d*)",new[0])[-1] 
        sta = re.findall("([\+\-\/]?\d+\.?\d*)",new[1])[0] 
        if li[i] == "*": 
            new_che = float(la) * float(sta) 
        else: 
            new_che = float(la) / float(sta) 
        arg = new[0][0:-len(la)] + str(new_che) +new[1][len(sta):] 
    arg=[arg,] 
    return compte_add_sub(arg) 
def comput(expression): 
    inp = [expression,] 
    n= compute_mul_div(inp) 
    return n 
def excut(expression): 
    kuohao=[] 
    if expression.find("(") == -1: 
        ret = comput(expression) 
        return ret 
    for i in range(len(expression)): 
        if "(" == expression[i]: 
            kuohao.append(i) 
        elif ")" == expression[i]: 
            ans_kuo = expression[kuohao[-1]+1:i] 
            ret_num = comput(ans_kuo) 
            expression = expression[0:kuohao[-1]]+str(ret_num)+expression[i+1:] 
            return excut(expression) 
def main(): 
    a = '1 - 2 * ((60-30 +(1-40/5*5+3-2*5/3) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))'
    default = '1-40/5*5+3-2*5/3'
    a = default if len(a) == 0 else re.sub("\s*", '', a)  # 三元運算給a默認值,否則 給表達式去除空格 
    ret = excut(a) # 調用excut 方法 並將返回值給ret 
    print("\033[33;1m公式為:\033[0m",a) 
    print("\033[35;1m結果為:\033[0m",ret) 
if __name__ == '__main__': 
    start = time.clock() 
    main() 
    end = time.clock() 
    print("read: %f s" % (end - start)) 
計算器

結果

C:\Python35\python3.exe E:/py_test/s3_py/real_cal_liujianzuo.py 
公式為: 1-2*((60-30+(1-40/5*5+3-2*5/3)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) 
結果為: 13652214.56825397
read: 0.001188 s 

version1 

#!/usr/bin/env python 
# _*_ coding:utf-8 _*_ 

import re 
def compte_add_sub(inp): 
    # inp = ['-9-8.8++9--9',] 
    arg = inp[0]  # 傳入的只剩下 加減的字符串為列表 獲取第一個值 
    #去除++ +- -- -+ 
    if arg.find("+-") != -1 or arg.find("-+") != -1: 
        arg = arg.replace("+-","-",len(arg)) 
        arg = arg.replace("-+","-",len(arg)) 
    elif arg.find("++") != -1  or arg.find("--") != -1: 
        arg = arg.replace("++","+",len(arg)) 
        arg = arg.replace("--","+",len(arg)) 
    new_m = re.search('[\-]*\d+\.*\d*[\-\+]+\d+\.*\d*',arg) # 匹配 -9.9 + 9.9 或者 -9.9 - 9.9 
    if not new_m: 
        # print(arg) 
        return arg  # 遞歸處理,當匹配不到上面的表達式就將表達式結果返回  即處理加減后的結果 
    else: 
        brefor,after = re.split('[\-]*\d+\.*\d*[\+\-]+\d+\.*\d*',arg,1) #以匹配到的表達式為分隔符 分割 
        new_m=new_m.group() #定義成列表 將匹配到的表達式 
        if new_m.find("+") != -1: #如果匹配的是+號 
            new_m=new_m.split("+") #以+號分割 
            # print(new_m) 
            zhi = float(new_m[0]) + float(new_m[1])  #計算加號 
        else: #減號的話 
            if new_m.startswith("-"): #如果匹配到的表達式以減號開頭 #對應的序列元素第一個是空 
                new_m=new_m.split("-") #以減號分割 
                zhi = -(float(new_m[1]) + float(new_m[2]))  #提出減號 內部相加即可 
                # print(zhi) 
            else: #如果不以減號開頭則 直接按分割收的序列 
                new_m=new_m.split("-") 
                # print(new_m) 
                zhi = float(new_m[0]) - float(new_m[1]) 
    #zhi = float('%0.6f'%zhi)  #浮點數優化精度 
    #print(zhi) 
    arg = brefor + str(zhi) +after #字符串類型進行拼接 
    # print(arg) 
    inp = [arg,] #更改列表 
    # print(inp) 
    return compte_add_sub(inp) 
#處理乘除 
def compute_mul_div(arg): 
    #arg = ['9-2*5/3+7/3*99/4*2998+10*568/14', 0] 
    val = arg[0]  #取出表達式 
    ###########計算平方########## 
    val = re.sub("(//)","/",val) 
    #print(arg) 
    while True: 
        x = re.search("\d+\.*\d*(\*\*)\d+\.*\d*",val) 
        if x: 
            expre = x.group() 
            print(expre) 
            x = x.group().split("**") 
            ret = float(x[0]) ** float(x[-1]) 
            if "e" in str(ret): 
                ret=int(ret) 
            #print(ret) 
            val = val.replace(expre,str(ret),1) 
            print(val) 
        else: 
            #print("exit") 
            break
    ###########計算平方########## 
    mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val) # 由於遞歸,首先判斷傳入的表達式滿足要求與否, 例子: 9.9 * 9.8 或者 9.9 /9.8  是否包含。 
    if not mch: 
        return  #退出函數 因為arg是列表與comput的inp列表指向的同一個內存地址,故不需要返回值 
    content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val).group()  #存在 例子: 9.9 * 9.8 或者 9.9 /9.8  的話取出 
    if len(content.split('*')) > 1: # 判斷是否* 進行分割查看長度,有*的話則會大於1 沒有就是/ 
        n1, n2 = content.split('*') 
        value = float(n1) * float(n2) 
    else: 
        n1, n2 = content.split('/') 
        value = float(n1) / float(n2) 
    #value = float('%0.7f'%value)  #float 類型取7個精度 即小數點后7位,否則太長影響效率 
    before, after= re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val, 1)  #以表達式進行分割,1是從左到右 匹配第一個合適的。   類似 字符串的split 
  
    new_str = '%s%s%s' % (before, value, after) #拼接 
    # print(new_str) 
    arg[0] = new_str   #更新列表的值 
    return compute_mul_div(arg)  #遞歸處理 
def comput(expression): 
    # expression = "9-2*5/3+7/3*99/4*2998+10*568/14" 
    #將傳入的四則做成列表 這樣修改函數形參則該列表也變化,因此不用return也行 
    inp = [expression,] 
    # 處理乘除 方法 
    compute_mul_div(inp) 
    # 處理加減 
    return compte_add_sub(inp) 
def excut(expression): 
    kuohao=[] # 左括號 索引加入列表 
    if expression.find("(") == -1: #如果匹配不到左括號就直接交給計算四則的函數 
        ret = comput(expression) 
        return ret 
    for i in range(len(expression)): 
        if "(" == expression[i]: # 循環字符串,遇到左括號加入空列表 
            kuohao.append(i) 
        elif ")" == expression[i]: # 一旦遇到右括號,就跟上面左括號列表的最后一個元素還有遇到的這個右括號進行切片 
            ans_kuo = expression[kuohao[-1]+1:i] 
            ret_num = comput(ans_kuo) 
            expression = expression[0:kuohao[-1]]+str(ret_num)+expression[i+1:] 
            print(expression) 
            return excut(expression) 
    # # \(([\+\-\*\/]*\d+\.*\d*){2,}\)  是找 這一類 :  括號開始  接+ - * / 然后是數字1個或多個 小數點 數字0個或多個 類似-77.77   至少匹配2次  然后 括號結尾  : (-77.9*-88+99/3) 
    # if not re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expresiong): 
    #     final = comput(expresiong)  #匹配不到了就交個這個計算四則的方法 
    #     return final 
    # jus = re.search('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expresiong).group()  #取得括號表達式  (1-40/5*5+3-2*5/3) 
    # #print(jus) 
    # befor, nothing, after = re.split('\(([\+\-\*\/]*\d+\.*\d*){2,}\)', expresiong, 1) #以單層括號表達式分割 (1-40/5*5+3-2*5/3) 比如, 作為分隔符 但是只顯示/3 這部分,所以先在上面取到表達式 
    # #print(nothing) 
    # jus = jus[1:len(jus) - 1]  #去除 分割表達式的括號 :1-40/5*5+3-2*5/3 
    # #print('222', jus) 
    # result = comput(jus) #交給四則運算的方法 
    # result = float(result) 
    # #result = float('%0.7f'%result) 
    # result=str(result) 
    # #print(result) 
    # new_expression = "%s%s%s" % (befor, result, after) #四則計算完后拼接 
    # # print(new_expression) 
    # return excut(new_expression) #將新的表達式返回給函數 ,遞歸處理 
def main(): 
  
    # a = '1 - 2 * ((60-30 +(1-40/5*5+3-2*5/3) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))' 
    default = '1-2*(3+4)-6/3-6+7'
    a = input("\033[35;1m請輸入表達式,只能包含小數點 四則運算符 小括號\n表達式:\033[0m") 
    lx = re.sub("[\d+\.\+\-\*\/\s*\(\)]","",a) 
    if len(lx) != 0: 
        print("\033[31;1m表達式有其他特殊符號\033[0m") 
        return main() 
    if "(" in a: 
        if a.count("(") != a.count(")"): 
            print("\033[31;1m表達式括號個數不匹配\033[0m") 
            return main() 
    a = default if len(a) == 0 else re.sub("\s*", '', a)  # 三元運算給a默認值,否則 給表達式去除空格 
    ret = excut(a) # 調用excut 方法 並將返回值給ret 
    print("\033[33;1m公式為:\033[0m",a) 
    print("\033[35;1m結果為:\033[0m",ret) 
  
  
  
  
  
if __name__ == '__main__': 
    main() 
版本1

version2 

#!/usr/bin/env python 
# _*_ coding:utf-8 _*_ 

import re 
def compte_add_sub(inp): 
    # inp = ['-9-8.8++9--9',] 
    arg = inp[0]  # 傳入的只剩下 加減的字符串為列表 獲取第一個值 
    #去除++ +- -- -+ 
    if arg.find("+-") != -1 or arg.find("-+") != -1: 
        arg = arg.replace("+-","-",len(arg)) 
        arg = arg.replace("-+","-",len(arg)) 
    elif arg.find("++") != -1  or arg.find("--") != -1: 
        arg = arg.replace("++","+",len(arg)) 
        arg = arg.replace("--","+",len(arg)) 
    new_m = re.search('[\-]*\d+\.*\d*[\-\+]+\d+\.*\d*',arg) # 匹配 -9.9 + 9.9 或者 -9.9 - 9.9 
    if not new_m: 
        #print(1766666,arg) 
        return arg  # 遞歸處理,當匹配不到上面的表達式就將表達式結果返回  即處理加減后的結果 
    else: 
        brefor,after = re.split('[\-]*\d+\.*\d*[\+\-]+\d+\.*\d*',arg,1) #以匹配到的表達式為分隔符 分割 
        new_m=new_m.group() #定義成列表 將匹配到的表達式 
        if new_m.find("+") != -1: #如果匹配的是+號 
            new_m=new_m.split("+") #以+號分割 
            # print(new_m) 
            zhi = float(new_m[0]) + float(new_m[1])  #計算加號 
        else: #減號的話 
            if new_m.startswith("-"): #如果匹配到的表達式以減號開頭 #對應的序列元素第一個是空 
                new_m=new_m.split("-") #以減號分割 
                zhi = -(float(new_m[1]) + float(new_m[2]))  #提出減號 內部相加即可 
                # print(zhi) 
            else: #如果不以減號開頭則 直接按分割收的序列 
                new_m=new_m.split("-") 
                # print(new_m) 
                zhi = float(new_m[0]) - float(new_m[1]) 
    #zhi = float('%0.6f'%zhi)  #浮點數優化精度 
    #print(zhi) 
    arg = brefor + str(zhi) +after #字符串類型進行拼接 
    # print(arg) 
    inp = [arg,] #更改列表 
    # print(inp) 
    return compte_add_sub(inp) 
#處理乘除 
def compute_mul_div(arg): 
    arg = arg[0] 
    #print(arg) 
    end =len(arg) 
    ###########計算平方########## 
    arg = re.sub("(//)","/",arg) 
    #print(arg) 
    while True: 
        x = re.search("\d+\.*\d*(\*\*)\d+\.*\d*",arg) 
        if x: 
            expre = x.group() 
            print(expre) 
            x = x.group().split("**") 
            ret = float(x[0]) ** float(x[-1]) 
            if "e" in str(ret): 
                ret=int(ret) 
            #print(ret) 
            arg = arg.replace(expre,str(ret),1) 
            print(arg) 
        else: 
            #print("exit") 
            break
    ###########計算平方########## 
    # num = arg.count("*",0,end) +arg.count("/",0,end) 
    li = re.findall(r"[*/]",arg) #匹配 * / 做到列表 
    #print(li) 
    num = len(li) 
    for i in range(num):  #循環列表的下標 
        new = arg.split(li[i],1) #以乘除號為分隔符進行分割 
        la=re.findall("[\+\-\/]?(\d+\.?\d*)",new[0])[-1] #獲取分隔符左側字符串的最后一個數字,匹配浮點數 
        sta = re.findall("([\+\-\/]?\d+\.?\d*)",new[1])[0] #獲取分隔符右側字符串的第一一個數字,匹配浮點數 
        #print(la,sta) 
        if li[i] == "*": #如果分隔符是* 計算乘 
            new_che = float(la) * float(sta) 
        else: 
            new_che = float(la) / float(sta) 
        #print(new_che) 
        # arg = re.sub(la+"*"+sta,new_che,new,1) 
        arg = new[0][0:-len(la)] + str(new_che) +new[1][len(sta):] # 分割拼接 
        #print(arg) 
    arg=[arg,] 
    #print(3333333333,arg) 
    return compte_add_sub(arg) 
  
def comput(expression): 
    # expression = "9-2*5/3+7/3*99/4*2998+10*568/14" 
    #將傳入的四則做成列表 這樣修改函數形參則該列表也變化,因此不用return也行 
    inp = [expression,] 
    # 處理乘除 方法 
    n= compute_mul_div(inp) 
    return n 
def excut(expression): 
    kuohao=[] 
    if expression.find("(") == -1: 
        ret = comput(expression) 
        return ret 
    for i in range(len(expression)): 
        if "(" == expression[i]: 
            kuohao.append(i) 
        elif ")" == expression[i]: 
            ans_kuo = expression[kuohao[-1]+1:i] 
            ret_num = comput(ans_kuo) 
            expression = expression[0:kuohao[-1]]+str(ret_num)+expression[i+1:] 
            #print(expression) 
            return excut(expression) 
def main(): 
    # a = '1 - 2 * ((60-30 +(1-40/5*5+3-2*5/3) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))' 
    default = '1-2*(3+4)-6/3-6+7'
    a = input("\033[35;1m請輸入表達式,只能包含小數點 四則運算符 小括號\n表達式:\033[0m") 
    lx = re.sub("[\d+\+\.\-\*\/\s*\(\)]","",a) 
    if len(lx) != 0: 
        print("\033[31;1m表達式有其他特殊符號\033[0m") 
        return main() 
    if "(" in a: 
        if a.count("(") != a.count(")"): 
            print("\033[31;1m表達式括號個數不匹配\033[0m") 
            return main() 
    a = default if len(a) == 0 else re.sub("\s*", '', a)  # 三元運算給a默認值,否則 給表達式去除空格 
    ret = excut(a) # 調用excut 方法 並將返回值給ret 
    print("\033[33;1m公式為:\033[0m",a) 
    print("\033[35;1m結果為:\033[0m",ret) 
    # "1-2*60-30+1-40/5*5+3-2*5/3*9-2*5/3+7/3*99/4*2998+10*568/14--4*3/16-3*2" 
if __name__ == '__main__': 
    main() 
版本2

version3

#!/usr/bin/env python 
# _*_ coding:utf-8 _*_ 

import re,time 
def compte_add_sub(inp): 
    arg = inp[0]  # 傳入的只剩下 加減的字符串為列表 獲取第一個值 
    if arg.find("+-") != -1 or arg.find("-+") != -1: 
        arg = arg.replace("+-","-",len(arg)) 
        arg = arg.replace("-+","-",len(arg)) 
    elif arg.find("++") != -1  or arg.find("--") != -1: 
        arg = arg.replace("++","+",len(arg)) 
        arg = arg.replace("--","+",len(arg)) 
    arg = re.findall("[\+\-]|\d+\.?\d*",arg) # 
    if arg[0] == "-": 
        arg[0]=arg[0]+arg[1] 
        del arg[1] 
    add_sum = float(arg[0]) 
    for i in range(1,len(arg),2): 
        if arg[i] == "+": 
            add_sum +=float(arg[i+1]) 
        elif arg[i] == "-": 
            add_sum -= float(arg[i+1]) 
    return add_sum 
def compute_mul_div(arg): 
    arg = arg[0] 
    end =len(arg) 
    ###########計算平方########## 
    arg = re.sub("(//)","/",arg) 
    #print(arg) 
    while True: 
        x = re.search("\d+\.*\d*(\*\*)\d+\.*\d*",arg) 
        if x: 
            expre = x.group() 
            print(expre) 
            x = x.group().split("**") 
            ret = float(x[0]) ** float(x[-1]) 
            if "e" in str(ret): 
                ret=int(ret) 
            #print(ret) 
            arg = arg.replace(expre,str(ret),1) 
            print(arg) 
        else: 
            #print("exit") 
            break
    ###########計算平方########## 
    li = re.findall(r"[*/]",arg) 
    num = len(li) 
    for i in range(num): 
        new = arg.split(li[i],1) 
        la=re.findall("[\+\-\/]?(\d+\.?\d*)",new[0])[-1] 
        sta = re.findall("([\+\-\/]?\d+\.?\d*)",new[1])[0] 
        if li[i] == "*": 
            new_che = float(la) * float(sta) 
        else: 
            new_che = float(la) / float(sta) 
        arg = new[0][0:-len(la)] + str(new_che) +new[1][len(sta):] 
    arg=[arg,] 
    return compte_add_sub(arg) 
def comput(expression): 
    inp = [expression,] 
    n= compute_mul_div(inp) 
    return n 
def excut(expression): 
    # kuohao=[] 
    # if expression.find("(") == -1: 
    #     ret = comput(expression) 
    #     return ret 
    # for i in range(len(expression)): 
    #     if "(" == expression[i]: 
    #         kuohao.append(i) 
    #     elif ")" == expression[i]: 
    #         ans_kuo = expression[kuohao[-1]+1:i] 
    #         ret_num = comput(ans_kuo) 
    #         expression = expression[0:kuohao[-1]]+str(ret_num)+expression[i+1:] 
    #         return excut(expression) 
    n = re.search("\(([^()]+)\)",expression) 
    if not n: 
        ret = comput(expression) 
        return ret 
    comp = n.group() # (1-40/5*5+3-2*5/3) 
    print(comp) 
    # sp = re.split("\(([^()]+)\)",expression,1) 
    before,nothing,after = re.split("\(([^()]+)\)",expression,1) 
    result = comput(comp[1:-1]) 
    expression = "%s%s%s"%(before,result,after) 
    return  excut(expression) 
def main(): 
    default = '1 - 2 * ((60-30 +(1-40/5*5+3-2*5/3) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))'
    default = re.sub("\s*", '', default) 
    a = input("\033[35;1m請輸入表達式,只能包含小數點 四則運算符 小括號\n表達式:\033[0m") 
    lx = re.sub("[\d+\.\+\-\*\/\s*\(\)]","",a) 
    if len(lx) != 0: 
        print("\033[31;1m表達式有其他特殊符號\033[0m") 
        return main() 
    if "(" in a: 
        if a.count("(") != a.count(")"): 
            print("\033[31;1m表達式括號個數不匹配\033[0m") 
            return main() 
    a = default if len(a) == 0 else re.sub("\s*", '', a)  # 三元運算給a默認值,否則 給表達式去除空格 
    ret = excut(a) # 調用excut 方法 並將返回值給ret 
    print("\033[33;1m公式為:\033[0m",a) 
    print("\033[35;1m結果為:\033[0m",ret) 
if __name__ == '__main__': 
    main() 
View Code

 


免責聲明!

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



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