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)) 
计算器

相关文章: