• 【笔记】Python基础七:正则表达式re模块


    一,介绍

    正则表达式(RE)是一种小型的,高度专业化的编程语言,在python中它内嵌在python中,并通过re模块实现。正则表达式模式被编译成一系列的字节码,然后由C编写的匹配引擎执行。

     字符匹配(普通字符,元字符):

    1 普通字符:大多数字符和字母都会和自身匹配
                  >>> re.findall('alex','yuanaleSxalexwupeiqi')
                          ['alex'] 

    2 元字符:. ^ $ * + ? { } [ ] | ( )

     二,元字符

    (一)点.通配符,代替除了换行符 以外的任意一个字符

    >>> import re
    >>> re.findall("alex","sdffalexjj")
    ['alex']
    >>> re.findall("a..x","sdffalexjj")
    ['alex']
    >>> re.findall("a...x","sdffalexjj")
    []

    (二)尖角号^,表示以后面的字符串开头;$符,表示以前面的字符串结尾。

    >>> re.findall("^a..x","asdffalexjj")
    []
    >>> re.findall("^a..x","asdxfalexjj")
    ['asdx']
    >>> re.findall("a..x$","asdxfa22x")
    ['a22x']

    (三)重复符号,* + ? { }

    1,*是重复紧挨着的字符,从0次到无穷次

    >>> re.findall("alex*","asdxfale")
    ['ale']

    2,+是1到无穷次,如果没有(0次)就匹配不上

    >>> re.findall("alex+","asdxfale")
    []
    >>> re.findall("alex+","asdxfalexxx")
    ['alexxx']

    3,?是0或者1次

    >>> re.findall("alex?","asdxfalexxx")
    ['alex']
    >>> re.findall("alex?","asdxfale")
    ['ale']

    4,{}自定义范围   {0,}==*   {1,}==+   {0,1}==?  {6}==重复6次  {1,6}重复1到6次

    >>> re.findall("alex{6}","asdxfalexxxxxx")
    ['alexxxxxx']
    >>> re.findall("alex{6}","asdxfalex")
    []
    >>> re.findall("alex{0,1}","asdxfalex")
    ['alex']
    >>> re.findall("alex{0,1}","asdxfale")
    ['ale']

    注意*,+,?等都是贪婪匹配,后面加?号使其变成惰性匹配

    >>> re.findall('abc*?','abcccccc')
    ['ab']
    >>> re.findall('abc*','abcccccc')
    ['abcccccc']
    >>> re.findall('abc+?','abcccccc')
    ['abc']

    (四)字符集[]

    实现或的逻辑

    >>> re.findall('x[yz]','xyuuxzuu')
    ['xy', 'xz']
    >>> re.findall('x[yz]p','xypuuxzuu')
    ['xyp']
    >>> re.findall('x[y,z]p','xypuuxzuux,p')
    ['xyp', 'x,p']

     []内只有三个字符例外

    1,-表示范围

    >>> re.findall('x[a-z]','xypuuxzuux,p')
    ['xy', 'xz']
    >>> re.findall('x[a-z]*','xypuuxzuux')
    ['xypuuxzuux']
    >>> re.findall('x[a-z]*','xypuuxzuux9n')
    ['xypuuxzuux']

    2,^非

    >>> re.findall('x[^a-z]','x12')
    ['x1']
    >>> re.findall('x[^a-z]','xy')
    []
    >>> re.findall("([^()]*)","12+(34*6+2-5*(2-1))")
    ['(2-1)']

     3,  后面跟元字符去除特殊功能,比如.

              后面跟普通字符实现特殊功能,比如d

    d  匹配任何十进制数;它相当于类 [0-9]。
    D 匹配任何非数字字符;它相当于类 [^0-9]。
    s  匹配任何空白字符;它相当于类 [ fv]。
    S 匹配任何非空白字符;它相当于类 [^ fv]。
    w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
    W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
      匹配一个特殊字符边界,比如空格 ,&,#等

    >>> re.findall("d","12+(34*6+2-5*(2-1))")
    ['1', '2', '3', '4', '6', '2', '5', '2', '1']
    >>> re.findall("d+","12+(34*6+2-5*(2-1))")
    ['12', '34', '6', '2', '5', '2', '1']
    >>> re.findall("[0-9]+","12+(34*6+2-5*(2-1))")
    ['12', '34', '6', '2', '5', '2', '1']
    >>> re.findall("D+","12+(34*6+2-5*(2-1))")
    ['+(', '*', '+', '-', '*(', '-', '))']
    >>> re.findall("D+","hello world")
    ['hello world']
    >>> re.findall("s+","hello world")
    [' ']
    >>> re.findall("S+","hello world")
    ['hello', 'world']
    >>> re.findall("w+","hello_world")
    ['hello_world']
    >>> re.findall("W+","~!@#$%^&*()")
    ['~!@#$%^&*()']
    >>> re.findall("www.baidu","www.baidu")
    ['www.baidu']

     的用法讨论。re.findall("I","I am ooo"),这里面python解释器会识别出,并处理后交给re模块,re模块收到的不再是,于是产生问题。

    解决方法1:使用r(raw string原生字符串)re.findall(r"I","I am ooo")

    解决方法2:使用\,由python解释器处理一次,去掉一个,传给re模块就变成,re.findall("I\b","I am ooo")

                        举例:找出"cl",反推re模块接收为"c\l",反推python解释器接收为"c\\l",最后re.findall("c\\l","I am oclo")   

    >>> re.findall("c\\l","I am oclo")
    ['c\l']

     (五)管道符|

    |之前是一部分,|之后是一部分,两者是或的关系

    >>> re.findall("ka|b","I am ka|b")
    ['ka', 'b']

    (六)分组介绍

    1,匿名分组使用()

    >>> re.findall("(abc)+","I am abcd")
    ['abc']

    注意:如果使用()分组,findall会优先显示匹配到的分组()里面的内容,而不是匹配的全部内容

               如果就想要www.baidu.com完整匹配,需要在括号里加入?:

    >>> re.findall("www.(baidu|163).com","dfsgfwww.baidu.com112")
    ['baidu']
    >>> re.findall("www.(?:baidu|163).com","dfsgfwww.baidu.com112")
    ['www.baidu.com']

      利用“优先显示匹配到的结果”解释下面的的现象

    >>> re.findall("(abc)+","I am abcabcabc")
    ['abc']

      上面实际把abc作为一个整体匹配,匹配到1次,结果是abcabcabc,但是只显示1个abc。如果想要全部显示,则需要使用上面的?:,如下:

    >>> re.findall("(?:abc)+","I am abcabcabc")
    ['abcabcabc']

      这种整体分组使用括号()匹配和单个字符匹配abc+是不一样的,如下abc+匹配到了3次而不是像上面分组的1次

    >>> re.findall("abc+","I am abcabcabc")
    ['abc', 'abc', 'abc']

      同理,分组的匹配出现多次的情况:

    >>> re.findall("(abc)+","I am abcabc111abc")
    ['abc', 'abc']

    2,命名分组:?P<name>对匹配没有任何影响,只是起了一个分组的名字叫name,而name作为group方法调用的参数。实际对匹配起作用的仍然是[a-z]+)d+

    >>> re.search("(?P<name>[a-z]+)d+","alex36wusir34xialv33").group()
    'alex36'
    >>> re.search("(?P<name>[a-z]+)d+","alex36wusir34xialv33").group("name")
    'alex'
    >>> re.search("(?P<name>[a-z]+)(?P<age>d+)","alex36wusir34xialv33").group("age")
    '36'

    三,方法

    1,findall,返回所有满足匹配条件的结果,放在列表里

    2,serach,在字符串内查找模式匹配,找到第一个然后返回一个对象。通过调用group()方法得到匹配的字符串,如果字符串没有匹配返回None

    3,match,只会在开始处进行匹配

    >>> re.match("(d+)","alex36wusir34xialv33")
    >>> re.match("(d+)","56alex36wusir34xialv33")
    <_sre.SRE_Match object; span=(0, 2), match='56'>
    >>> re.match("(d+)","56alex36wusir34xialv33").group()
    '56'

    4,split,分割函数

    >>> re.split("[ |]","hello abc|def")
    ['hello', 'abc', 'def']
    >>> re.split("[ab]","asdabcd")
    ['', 'sd', '', 'cd']
    >>> re.split("[ab]","abc")
    ['', '', 'c']

    5,sub,替换函数,4个参数:1:模式,2:替换为字符,3:搜索字符串,4:替换次数

    >>> re.sub("d+","A","J12abc234ffg55")
    'JAabcAffgA'
    >>> re.sub("d","A","J12abc234ffg55")
    'JAAabcAAAffgAA'
    >>> re.sub("d","A","J12abc234ffg55",4)
    'JAAabcAA4ffg55'
    >>> re.subn("d","A","J12abc234ffg55")
    ('JAAabcAAAffgAA', 7)

    6,compile,模式先编译好,以后就可以直接调用。好处是写一次可以使用多次提高效率。

    >>> com=re.compile("d+")
    >>> com.findall("fjlkdad234hfjksd3421")
    ['234', '3421']
    >>> com.findall("444adf555")
    ['444', '555']

    7,finditer,返回的是迭代器对象,不再是列表。好处和迭代器是一样的。

    >>> ret=re.finditer("d","sdfds123fr")
    >>> next(ret).group()
    '1'
    >>> next(ret).group()
    '2'

    参考:http://www.cnblogs.com/yuanchenqi/articles/5732581.html

  • 相关阅读:
    Luogu P5853 [USACO19DEC]Tree Depth P
    Luogu P6009 [USACO20JAN]Non-Decreasing Subsequences P
    HDU6309 Absolute
    Luogu P4734 [BalticOI 2015]Hacker
    Gym102431F Ferry
    Gym102431G Game on the Tree
    AGC018F Two Trees
    Gym102268D Dates
    AGC023F 01 on Tree
    CF700E Cool Slogans
  • 原文地址:https://www.cnblogs.com/fudonghai/p/10356671.html
Copyright © 2020-2023  润新知