正则表达式

正则表达式
    动机
        1. 文本处理已经成为计算机的常见工作之一
        2. 对文本内容的搜索,定位,提取是逻辑比较复杂的
        3. 为了快速方便的解决上述问题,产生了正则表达式技术。
    定义:
        即文本的高级匹配模式,提供搜索,替代等功能。本质是由一系列特殊符号和字符组成的字串,这个字串即是正则表达式。这个表达式描述了字符和字符的重复行为,可以匹配一类特征的字符串。
    目标:
        1.熟练掌握正则表达式符号
        2.能够编写一定程度的正则表达式和理解较难的正则
        3.能够使用python 操作正则表达式
    特点:
        * 方便进行检索修改的文本操作
        * 支持语言众多
        * 使用灵活多样

python  ---->re模块  标准模块,专门用于处理正则表达式
    re.findall(pattern,string)
        功能:使用正则表达式匹配字符串,在string中有多少个pattern就会匹配多少次,只要出现符合pattern表达式,就会被匹配到,然后作为返回列表的一个元素
        参数:pattern  正则表达式
             string   目标字符串
        返回值:返回一个列表,列表中为匹配到的内容
        元字符 (即正则表达式中有特殊含义的符号)
            In [1]: import re
            In [2]: s = "My email is lvze@tedu.cn"
            In [3]: p = "\w+@\w+\.cn"
            In [4]: re.findall(p,s)
            Out[4]: ['lvze@tedu.cn']

    1. 普通字符
        元字符: a b c
        匹配规则:匹配相应的字符
            In [5]: re.findall('abc',"abcdefgabcdab")
            Out[5]: ['abc', 'abc']
            In [6]: re.findall('你好',"小平,你好") #汉字符也是可以的
            Out[6]: ['你好']
    2. 或
        元字符  |
        匹配规则:匹配 | 两边任意一个正则表达式的内容  一个字符findall()只能匹配一次,比如re.findall('ab|bc','abcdefg') 输出是[ab], 而不会有bc项,b不会重复匹配。
            In [11]: re.findall('ab|cd','abcdefgabasdfcd')
            Out[11]: ['ab', 'cd', 'ab', 'cd']
            * |左右不要加没用的空格

    3. 匹配单一字符
        元字符:  .
        匹配规则:匹配除换行外的任意字符(即\n意外的任意字符)
        f.o  --> foo   fao  f@o
            In [13]: re.findall('f.o','foo is not fao')
            Out[13]: ['foo','fao'] #.只能匹配单一字符,即一个字符,若想匹配多个字符只需要继续用.符号连接使用就行。
            In [9]: re.findall('f.a.o','foamo is not fao')
            Out[9]: ['foamo']
    4. 匹配开始位置
        元字符: ^
        匹配规则:匹配字符串的开头位置,不是开始位置是匹配不了的
            ^Hello  --> Hello world : Hello
            In [16]: re.findall('^hello','hello world')
            Out[16]: ['hello']

    5. 匹配结束位置
        元字符 : $
        匹配规则: 匹配目标字符串的结束位置
        py$ ---> hello.py
            In [18]: re.findall('py$','hello.py')
            Out[18]: ['py']
    6. 匹配重复
        元字符:  *
        匹配规则: 匹配前面的那个字符0次或无限次 即*号前面那个单字母匹配0-n次,
        fo* --->  foo  foooooo  f
            In [21]: re.findall('ab*','ababbbcadfsdf')
            Out[21]: ['ab', 'abbb', 'a']
    7. 匹配重复
        元字符 : +
        匹配规则: 匹配前面的那个字符一次或无限次
            ab+   a   ab  #ab本来是要匹配的普通表达式,后面跟了+号后则表示'a+1~n个b'的表达式可以被匹配1到无限次
            In [23]: re.findall('.+py$','hello.py')  #'.'是匹配除了\n以外任意字符,'.+'则意味着会一直往前匹配直到遇到'\n'
            Out[23]: ['hello.py']

            In [18]: re.findall('ab+','aaaabbaaabbbb.py')
            Out[18]: ['abb', 'abbbb']


    8. 匹配重复
        元字符: ?
        匹配规则: 匹配前面的那个字符0次或1次  #
            ab?   a   ab  #ab本来是要匹配的普通表达式,后面跟了?号后则表示'a+0/1个b'的表达式可以被匹配
            In [24]: re.findall('ab?','ablkasdjfabbbbb')
            Out[24]: ['ab', 'a', 'ab']

    9. 匹配重复
        元字符: {n}
        匹配规则: 匹配{n}前面的字符n次 n是指定的重复次数
            ab{3} ----> abbb
            In [26]: re.findall('ab{3}','abbbbbbbbb')
            Out[26]: ['abbb']

    10. 匹配重复
        元字符:{m,n}
        匹配规则:匹配前面的正则表达式m-n次  {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次
        ab{3,5} -->  abbb  abbbb  abbbbb
            In [28]: re.findall('ab{2,4}','absadfeaabbb')
            Out[28]: ['abbb']

    11. 匹配字符集合
        元字符: [字符集]
        匹配规则:匹配括号内的任意一个字符
        [abc123d]  a b c 1 2 3 d
        [a-z]  
        [A-Z]
        [0-9]
        [123a-zA-Z]
            In [31]: re.findall('[_0-9a-zA-Z]+','hello world 123')
            Out[31]: ['hello', 'world', '123']

    12. 匹配字符集合
        元字符 : [^字符集]
        匹配规则: 匹配除了括号中字符集的任意一个字符  即求反集
        [^abc]  匹配除abc的任意一个字符
            In [34]: re.findall('[^abcd]','a little boy')
            Out[34]: [' ', 'l', 'i', 't', 't', 'l', 'e', ' ', 'o',y]

    13. 匹配任意(非)数字字符
        元字符:  \d     \D
        匹配规则:\d匹配任意数字字符  \D匹配任意非数字
            [0-9]               [^0-9]
            In [35]: re.findall('1\d{10}','17778965439')  
            Out[35]: ['17778965439']

    14. 匹配(非)普通字符 (数字字母下划线)
        元字符: \w     \W
        匹配规则: \w 普通字符  \W非普通字符
               [_0-9a-zA-Z]  [^_0-9a-zA-Z]
            In [38]: re.findall('\w+',"hello$1")
            Out[38]: ['hello', '1']

            In [39]: re.findall('\W+',"hello$1")
            Out[39]: ['$']

            In [40]: re.findall('\w+',"hello 成都")
            Out[40]: ['hello', '成都']
            * \w 可以匹配普通的utf-8字符(比如汉字)

    15.  匹配(非)空字符   (空格,\r \t \n \0)
        元字符 : \s   \S
        匹配规则: \s 空字符    \S 非空字符
            In [42]: re.findall('\s+',"hello   world\r\n\t\0")
            Out[42]: ['   ', '\r\n\t']

            In [43]: re.findall('\S+',"hello   world")
            Out[43]: ['hello', 'world']

    16.  匹配起止位置
        元字符 : \A     \Z
        匹配规则: \A 匹配开始位置  \Z匹配结束位置
        等同于        ^                $
            In [32]: re.findall('\Ahello',"hello world")
            Out[32]: ['hello']

            绝对匹配
            In [47]: re.findall('\Ahello\Z',"hello") \A和\Z可以用^和$符号替换
            Out[47]: ['hello']
        * 绝对匹配:使用开头和结尾位置的元字符将正则表达式放在其中,则目标字符串仅有正则匹配内容时   才能匹配上。

    17. 匹配(非)单词边界位置
          (普通字符和非普通字符的交界处为单词边界)
        元字符:        \b          \B
        匹配规则: \b单词边界位置  \B非单词边界
            In [52]: re.findall(r'\Bis',"This is a  test")
            #r是原生字符串,否则不会显示结果,\B只要左右两边有一个不是边界就可以被匹配到,而b%要求单词左右边界都是is的才会被匹配
            Out[52]: ['is']
            In [54]: re.findall(r'\b成都\b',"成都,成都接头走一走")
            Out[54]: ['成都']

    元字符总结
        匹配单个字符: a  .  \d  \D  \w  \W  \s  \S  [..]   [^..]
        匹配重复性 :*  +  ? {N} {m,n}
        匹配位置:^  $  \A  \Z  \b  \B
        其他: |  ()  \                


正则表达式转义
    正则中的特殊符号:
        .  *  ?  $  []  {}  ()  ^  \
            In [58]: re.findall('\w+@\w+\.cn',"lvze@tedu.cn")
            Out[58]: ['lvze@tedu.cn']
            In [62]: re.findall('.+\?$',"How are you?")
            Out[62]: ['How are you?']

        \w+@\w+\.cn ----》"lvze@tedu.cn"
    python 字符串转义
        \n  \t  \   "   '
        "nihao\\nchina"
    raw 字符串:原生字符串,字符串内容就是本身不进行任何转义
        用法: r"hello" 加了r后字符串内部的内容不会做任何的转义解析,通常正则表达式中有\符号最好加r符号
    贪婪与非贪婪
        贪婪模式:正则表达式的重复匹配默认总是尽可能多的向后匹配内容
        *   +   ?  {m,n}
    非贪婪模式:尽可能少的匹配内容
        贪婪--->非贪婪   *?  +? ??  {m,n}?
            In [78]: re.findall(r'ab*?',"abbbbb")
            Out[78]: ['a']

            In [79]: re.findall(r'ab+?',"abbbbb")
            Out[79]: ['ab']

正则表达式分组
    使用()可以为一个正则表达式建立子组,子组并不会影响正则表达式的整体匹配内容,子组可以看做是一个内部的整体部分
    子组的作用:
        1. 子组可以改变正则表达式的重复行为
        re.search(r'(ab)+',"ababababab").group()
        'ababababab'
        
        2. 子组在某些操作中可以被单独提取出来
        re.search(r'(ab)+',"ababababab").group(1)
        'ab
    子组的使用注意事项
        * 一个正则表达式中可以有多个子组,从外到内从左  到右分别为第一第二第三。。。。子组
        * 子组不存在交叉的情况

捕获组和非捕获组(命名组和非命名组)
    格式: (?P<name>pattern)
        1.很多编程接口可以直接通过名字获取子组匹配内容
        2.命名组可以被重复调用
          重复调用格式:(?P=name)
            In [93]: re.search(r'(?P<dog>ab)+',"ababababab").group()
            Out[93]: 'ababababab'

            In [94]: re.search(r'(?P<dog>ab)cdef(?P=dog)',"abcdefabcd").group()
            Out[94]: 'abcdefab'

            In [97]: re.search(r'\d{17}(\d|x)',"21803119950425135x").group()
            Out[97]: '21803119950425135x'

正则表达式使用要求
    1. 唯一性:正则表达式只能匹配目标类别字符串,而不能匹配其他内容
    2. 准确性:尽可能全面的考虑目标类别的字符串特征,做到不遗漏

re模块
    re模块内的方法:
        compile(),findall(),finditer(),fullmatch(),match(),search(),split(),sub(),subn()....等

    re.compile()
        regex = re.compile(pattern,flags = 0)
        功能: 生成正则表达式对象,(编译正则表达式模式,返回一个对象的模式。可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)
        参数: pattern  正则表达式
        flags:功能标志位,提供更丰富的筛选功能
            Flags:标志位(参数)re.I
            作用:辅助正则表达式,丰富匹配结果
            I == IGNORECASE   忽略大小写
            S == DOTALL   元字符 . 匹配  \n
            M == MULTILINE  元字符^ $可以以匹配每行的开头结尾
            X == VERBOSE  可以给正则添加注释
            多个标志位可以用 | 隔开    eg.   flags = re.X | re.I

        #flags 采用默认值0时表示不添加其他任何功能,如果不为0,flags的值必须是re模块自带属性中的常量(dir(re)中那些大写名属性),这些不同的常量传给flags可以在原来正则表达式基础上进一步丰富conpile()函数的筛选功能,比如不区分大小写等,re的方法基本上都带了这一个标志位,作用都一样的。
        返回值: 正则表达式对象
        compile()函数返回的正则表达式对象regex包含的方法(dir(regex))有:
            findall(),finditer(),fullmatch(),match(),search(),split(),subn(),compile()...
            上面有很多函数和re模块的方法名字一模一样,他们的功能也是一模一样,区别在于
                1、调用方法不一样,re.方法名() regex.方法名()
                2、两种方法的传参中regex方式少了pattern正则表达式这个参数,因为在compile()函数中就已经把正则表达式传入了,不需要再次传入,而re的方法必须指明正则表达式是什么,regex相当于分两步达到了re方式一步的效果。
                3、re方法调用时形参中会有一个flags标志位(默认等于0时不用写出来)regex调用没有,regex方法可以通过两个形参pos和endpos指定查找范围,而re不行
                eg.
                    import re
                    tt = "Tina is a good girl, she is cool, clever, and so on..."
                    rr = re.compile(r'\w*oo\w*')
                    print(rr.findall(tt))   #查找所有包含'oo'的单词findall()不用在传pattern
                    执行结果如下:
                    ['good', 'cool']

    re.findall(pattern,string,flags)
        功能:查找正则表达式匹配内容,re.findall()遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表。
        参数:pattern 正则表达式
        string  目标字符串
        lags  功能标志位
        返回值: 将匹配到的内容放入一个列表返回,如果有子组,只能返回子组匹配到的内容
                      
    regex.findall(string=None, pos=0,endpos=999)
        功能:查找正则表达式匹配内容
        参数:string 目标字符串
            pos: 匹配目标字符串的起始位置
            endpos:匹配目标字符串的结束位置            
        返回值: 将匹配到的内容放入一个列表返回
                 如果有子组,只能返回子组匹配到的内容

    re.split(pattern,string,flags=0)
        功能: 通过正则表达式分割目标字符串,按匹配到的分割
        参数: pattern 正则表达式
              string 目标字符串
        返回值: 返回分割后的字符串列表
        eg.
            l = re.split(r'\s+','hello world\nnihao  china') #按空字符类分割
            print(l)
            #['hello', 'world', 'nihao', 'china']


    re.sub(pattern,replaceStr,string,max,flags)
        功能:替换正则表达式匹配到的内容
        参数:pattern : 正则
             replstr : 要替换的内容
             string: 目标字符串
             max: 组多替换几处
             返回值: 返回替换后的字符串
             eg.
                s = re.sub(r'\s+','##','hello world nihao')
                    print(s)
                hello##world##nihao

    re.subn(pattern,replaceStr,string,max,flags)
        功能:替换正则表达式匹配到的内容
        参数:pattern: 正则
             replstr: 要替换的内容
             string: 目标字符串
             max: 组多替换几处
        返回值:返回替换后的字符串和实际替换的个数  和sub()的区别是返回值多了一个具体替换了几处
            s = re.subn(r'\s+','##','hello world nihao')
                print(s)
                ('hello##world##nihao', 2)   返回元组 第二个值为具体替换了多少个

    re.finditer()\refullmatch()\re.match()\re.search()
        四个函数返回的又是一个对象,称之为match对象,整个re模块分为三级,第一级是re模块层,第二级是正则对象regex层,第三级是match对象层。
        所谓match对象就是匹配对象,即绑定匹配的结果的变量
        match对象的方法和属性(dir(match对象));
            end(),endpos(),expand(),group(),groupdict(),groups,lastgroup,lastindex,pos,re,span,start,string....

    re.finditer(pattern,string,flags)
        功能:使用正则表达式匹配内容
        参数:pattern 正则表达式
             string   目标字符串
        返回值:返回匹配到的内容的迭代器对象,迭代器是match对象的迭代器
        要想获得匹配的值需要用到返回的match对象的方法group(),即obj.group()

    re.fullmatch(pattern,string,flags)
        功能:完全匹配目标字符串,类似于绝对匹配,所谓完全匹配就是要匹配的目标字符完全能匹配上,不允许出现不能匹配上的字符
        参数:pattern  正则
             string  目标字符串
        返回值:match对象,匹配不到返回None
        eg.
          1 obj = re.fullmatch('\w*','abcdefg123')
            #目标字符abcdefg123每个字符都满足\w*所以可以匹配上
            print(obj.group())
          2 obj = re.fullmatch('\w*','abcde#fg123')
            #目标字符abcde#fg123中#不满足\w*匹配条件,所以不能完全匹配。匹配失败
            print(obj.group())
            fullmatch()函数匹配失败是会返回None,所以此时print(obj.group())会报错。

    re.match(pattern,string,flags)
        功能:匹配目标字符串的开头,若字符串的开头满足pattern条件,则匹配成功,否则失败,返回None
        参数:pattern  正则
             string  目标字符串
        返回值:match对象,匹配不到返回None
        eg.
            obj = re.match(r'foo','food on the table')  
            print(obj.group())


    re.search(pattern,string,flags)
        功能:匹配目标字符串,只能匹配第一处
        参数:pattern  正则
             string  目标字符串
        返回值:match对象,匹配不到返回None:
        * 由于fullmatch  match search函数匹配不到会返回None,而None没有match对象的属性,没匹配到就会出现异常,所以往往需要用异常判断处理
        eg.
            obj = re.search(r'foo','The food on the table,foo')
            print(obj.group())
            返回:foo
    正则对象其他属性
        flags:  标志位,是整数,不一样的整数值代表不一样的意义
        pattern: 正则表达式
        groups: 有多少个子组  (regex.groups/regex.groupindex...)
        groupindex: 捕获组形成的字典
                    {组名为键:第几组为值}

match对象
    属性变量
        pos : 目标字符串的开头位置
        endpos : 目标字符串结束位置
        re : 正则表达式对象
        string : 目标字符串
        lastgroup:最后一组名字
        lastindex:最后一组是第几组

    属性方法
        start()  获取匹配到的内容的开始位置
        end()    获取匹配到的内容的结束位置
        span()   获取匹配到的内容的起止位置

    group(n = 0)
        功能:获取match对象对应匹配到的内容
        参数:默认为0表示获取正则表达式整体的匹配内容
             如果赋值1,2,3...则表示获取某个子组的匹配内容
        返回值:返回匹配字符串

    groups()  获取所有子组匹配内容
    groupdict() 将所有捕获组内容形成一个字典


    flags 参数

        re.compile re.findall re.search re.match
        re.finditer  re.fullmatch  re.sub  re.subn re.split

        作用: 辅助正则表达式,丰富匹配结果

        A == ASCII
        S == DOTALL   元字符.可以匹配\n
        I == IGNORECASE   或略大小写
        L == LOCALE
        M == MULTILINE 元字符^  $ 可以匹配每一行的开头                结尾位置
        T == TEMPLATE
        U == UNICODE
        X == VERBOSE   可以给正则添加注释

        同时使用多个flag 用 |
        re.I | re.S

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值