zoukankan      html  css  js  c++  java
  • Python基础之re模块(正则表达式)

      就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,

    并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

      字符匹配又分为两种:

      一、普通字符:

      大多数字符和字母都会和自身进行匹配。

    import re
    ret = re.findall("admin","hello administrator") #这是字符串的完整匹配
    print(ret)
    ---------输出结果-----------
    ['admin']
    

      二、元字符:

      元字符符号包括:" . ^ $ * + ? {} [] () | "。

      下面我们就来详细看看具体的含义和用法:

      1、元字符之 . ^ $ * + ? {} :

    ret = re.findall("a...n","hello administrator") #"."表示所有除
    之外的任何单个字符
    print(ret) #-----> ['admin']
    
    ret = re.findall("^h...o","hello administrator") #匹配输入字符串的开始位置
    print(ret) #-----> ['hello']
    
    ret = re.findall("r...r$","hello administrator") #匹配输入字符串的结束位置
    print(ret) #-----> ['rator']
    
    ret = re.findall("abc*","abccccc") #匹配前面的子表达式零次或多次
    print(ret) #-----> ['abccccc']
    
    ret = re.findall("abc+","abccccc") #匹配前面的子表达式一次或多次
    print(ret) #-----> ['abccccc']
    
    ret = re.findall("abc?","abccccc") #匹配前面的子表达式零次或一次
    print(ret) #-----> ['abc']
    
    ret = re.findall("abc{1,3}","abccccc") #{}自定义c出现的次数
    print(ret) #-----> ['abccc']
    

      注意:前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成非贪婪匹配(惰性匹配)。

    ret = re.findall("abc+?","abccccc") #非贪婪匹配
    print(ret) #-----> ['abc']
    ret = re.findall("abc*?","abcccc") #非贪婪匹配
    print(ret) #-----> ['ab']
    

      2、元字符之字符集[ ] :(起一个 或者 的意思),注意:. 、* 、+等元字符都是普通符号, - ^ 这几个有特殊意义

    ret = re.findall("a[bc]d","abd") #匹配a和d之间有b或者c
    print(ret) #-----> ['abd']
    ret = re.findall("a[bc]d","acd") #匹配a和d之间有b或者c
    print(ret) #-----> ['acd']
    
    ret = re.findall("[a-z]","hello") #匹配a-z之间的所有字母
    print(ret) #-----> ['h', 'e', 'l', 'l', 'o']
    
    ret = re.findall("[.*+?]","a.b*c+d?e") #在[ ]'.*+?'里没有特殊意义了,就是普通的字符
    print(ret) #-----> ['.', '*', '+', '?']
    #在字符集里有功能的符号:-(定义一个范围) ^(取反) (转义)
    
    ret = re.findall("[0-9]","12ab34cd56ef") #取出所有的数字
    print(ret) #-----> ['1', '2', '3', '4', '5', '6']
    
    ret = re.findall("[^ab]","12ab34cd56ef") #不取出ab
    print(ret) #-----> ['1', '2', '3', '4', 'c', 'd', '5', '6', 'e', 'f']
    
    ret = re.findall("[d]","12ab34cd56ef") #相当于[0-9]
    print(ret) #-----> ['1', '2', '3', '4', '5', '6']
    

      3、元字符之转义符 :

      反斜杠后边跟元字符去除特殊功能,比如.,此时.就没有特殊意义了,就是一普通字符。

      反斜杠后边跟普通字符实现特殊功能,详见下文:

        d  匹配任何十进制数;它相当于类 [0-9]

        D 匹配任何非数字字符;它相当于类 [^0-9]

        s  匹配任何空白字符;它相当于类 [ fv]

        S 匹配任何非空白字符;它相当于类 [^ fv]

        w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]

        W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]

          匹配一个特殊字符边界,比如空格 ,&,#等

    ret = re.findall("I","I am LIST") #此时结果为空,因为对应ASCII有特殊含义
    print(ret) #-----> []
    
    ret = re.findall(r"I","I am LIST") #r表示原生字符,里面的都没有特殊意义了
    print(ret) #-----> ['I']
    
    ret = re.findall("I\b","I am LIST") #在前加一个转义,此时就没有特殊意义了
    print(ret) #-----> ['I']
    
    # ret = re.findall("al","almn") #这个直接报错
    # ret = re.findall("a\l","almn") #这个也会报错
    ret = re.findall("a\\l","almn") #此时为什么会有那么多 () 呢?请看下文详解
    #因为我们前文也介绍过,正则表达式是内嵌在Python里的一种专业的编程语言,
    #因为 () 是有特殊含义的元字符,so,我们就应该给它转义以下,so,应为 (\),我们
    #要知道,Python解释器要先识别,然后把识别结果在交给正则表达式来处理,所以,
    #就应该有 (\\) 来进行转义,在这里其实,三个转义符,也是可以的,怎么理解呢,两个
    #转义符(\)经过Python识别后变成(),这个 () 加上后面的 (),就成了两个(\),这时,
    #正则表达式就能识别经过转义后的普通字符了。
    print(ret) #-----> ['a\l']
    ret = re.findall(r"a\l",r"allmn") #加上r使Python识别为原生字符,
    # 然后在两个\交给正则表达式来处理,不然就会报错了。
    print(ret) #-----> ['a\l']
    

      下面我们就来看看,一些有着特殊意义的字符,如:见图中的一些转义字符。

    ret = re.findall("\blike","I like manlike the motorcycle trip")
    print(ret) #-----> ['like']     #这里加上后,就只能匹配到一个like了。
    
    ret = re.findall(r"\book",r"penook") #因为有特殊的意义,跟上文一样
    print(ret) #-----> ['\book']  #这里里面的两个(\),是因为正则表达式要传给Python
                                              #自动加上了()了,我们可只看成['ook']
    

       4、元字符之分组 ( ):

      4.1、普通分组:

    ret = re.findall("(ad)+","dadadadddd") # 在一个连续的字符串里匹配到括号里的内容后,就停止匹配了
    print(ret) #-----> ['ad']
    
    ret = re.findall("(ad)+min","administrator") #会优先显示分组,即括号里的内容
    print(ret) #-----> ['ad']
    
    ret = re.findall("(ad)+min","adm admin administrator") #非连续的字符串里匹配到内容后,优先显示分组
    print(ret) #-----> ['ad', 'ad']
    
    ret = re.findall("(?:ad)+min","adm admin administrator adadmin") #括号里前面加上?:取消分组的优先级,就没有特殊意义了
    print(ret) #-----> ['admin', 'admin', 'adadmin']
    

      4.2、命名分组:

    ret = re.search(r"(?P<name>w+):(?P<age>d+)","michael:18") #对自己想取的部分进行命名操作
    print(ret.group("name")) #通过自己设的组名,得到对应的值
    print(ret.group("age")) #通过自己设的组名,得到对应的值
    ----------------输出结果--------------
    michael
    18
    

      5、元字符之 | :或的意思

    ret = re.findall("a|b","a") #a或者b符合条件,这里是a
    print(ret) #-----> ['a']
    ret = re.findall("a|b","b") #a或者b符合条件,这里是b
    print(ret) #-----> ['b']
    ret =re.search("D+|d+","123456") #数字字符与非数字字符,这里是数字
    print(ret.group()) #-----> 123456
    
    ret = re.search("D+|d+","admin") #数字字符与非数字字符,这里是非数字
    print(ret.group()) #-----> admin
    #|是或者的意思,即在前面的条件里,选一个。
    

      三、re模块下的常用方法:

      我们一起来总结一下都有哪些方法:

    #1、findall:匹配所有满足条件的结果
    ret = re.findall("ad","admin") #返回所有满足匹配条件的结果,放在一个列表里
    print(ret) #-----> ['ad']
    
    #2、search:只匹配第一个结果
    ret = re.search("ad","admin") #函数会在字符串内查找模式匹配,直到找到
                                  # 第一个匹配然后返回一个包含匹配信息的对象
    print(ret.group()) #通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
    # -----> ad
    
    #3、match:只匹配最开始位置
    ret = re.match("ad","admin") #同search,不过只在字符串开始处进行匹配,
                                 # 若开始处,不是匹配的内容,则报错
    print(ret.group()) #同上
    # -----> ad
    
    #4、split:分割
    ret = re.split("a","12a34a56") #按"a"分割,得到一个列表
    print(ret) # -----> ['12', '34', '56']
    ret = re.split("[ab]","a34b56") #先按"a"分割,得到""和"34b56",在对""和"34b56"
                                    #分别按"b"分割,""里没b,就没有效果,so,"34b56"
                                    #被分割为"34"和"56"
    print(ret) # -----> ['', '34', '56']
    
    #5、sub、subn:替换
    ret= re.sub("B","A","michael:B egon:B") #替换,第一个是定位信息,第二个是修改内容,
    print(ret) # -----> michael:A egon:A
    ret= re.sub("B","A","michael:B egon:B",1) #这里的1是传给count的值,表示替换的次数
    print(ret) # -----> michael:A egon:B
    ret = re.subn("B","A","michael:B egon:B") #跟sub比,它返回的是一个替换后的值是一个元组的形式
                                               #后面并且会显示统计替换的次数
    print(ret) # -----> ('michael:A egon:A', 2)
    
    #6、compile:编译方法
    obj = re.compile("d+")
    ret = obj.findall("123admin456") #相当于re.findall("d+","123admin456")
    print(ret) # -----> ['123', '456']
    

      我们需要注意一下:

    ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
    print(ret) #-----> ['oldboy'] 因为findall会优先把匹配结果放在组里将内容返回,
                                          # 如果想要匹配完整结果,取消权限即可
    
    ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
    print(ret) #-----> ['www.oldboy.com'] 加上(?:)即取消了分组的权限
    

      

  • 相关阅读:
    判断整除(动态规划,递推)
    Apollo 配置详细步骤(Windows环境)
    java的环境变量
    我的C++学习心得
    Maven实战_许晓斌
    深入理解计算机系统--中文版
    http 权威指南 -- http the definitive guide
    看原版英文和译版中文
    python 单元测试框架 pyunit
    在SQL Server 中创建外键
  • 原文地址:https://www.cnblogs.com/Michael--chen/p/6776385.html
Copyright © 2011-2022 走看看