zoukankan      html  css  js  c++  java
  • Python基础----正则表达式和re模块

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

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

    1 普通字符(完全匹配):大多数字符和字母都会和自身匹配

    1 >>> import re
    2 >>> res='hello world good morning'
    3 >>> re.findall('hello',res)
    4 ['hello']

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

    元字符

    .  通配符,匹配一个除了换行符的任意字符,中间如果有换行符也不会跳过换行符,只是无法匹配

    复制代码
     1 >>> import re
     2 >>> str1="hello
    ,张三"
     3 #re.findall()方法,第一个元素为匹配规则,第二个元素为字符串,返回的是所有匹配项的列表,re下的方法后面详细说明
     4 >>> re.findall("l",str1)    #遍历匹配l,如果匹配到,则输出为列表的一个元素
     5 ['l', 'l']
     6 >>> re.findall("h.",str1)   #匹配h开头,后面包含任意字符除换行符的两个字符
     7 ['he']
     8 >>> re.findall("hello.",str1)  #因为hello后的字符是换行符,所以匹配不到
     9 []
    10 >>> re.findall("张.",str1)    #包含的字符串在哪个位置匹配都可以
    11 ['张三']
    复制代码

    ^  开始匹配,只匹配字符串的开头,开头如果没有,后边不会再进行匹配

    1 >>> re.findall("^hello",str1)  #开头有hello所以匹配成功
    2 ['hello']
    3 >>> re.findall("^llo",str1)    #开头没有llo,匹配失败
    4 []

    $  结尾匹配,只匹配结尾

    复制代码
    1 >>> re.findall("llo$",str1)    #该字符串以三结尾
    2 []
    3 >>> re.findall("三$",str1)
    4 ['三']
    5 >>> re.findall("张三$",str1)    #可匹配多个字符
    6 ['张三']
    7 >>> re.findall("张.$",str1)    #不同的元字符联用
    8 ['张三']
    复制代码

    重复功能元字符

    ?  表示?前一个字符或组可有可无,范围即0次或1次

    1 >>> re.findall("ho?el",str1)  #o可有可无,匹配hel
    2 ['hel']
    3 >>> re.findall("he?l",str1)  #e可有可无,有的时候匹配hel
    4 ['hel']
    5 >>> re.findall("he?el",str1)  #第一个e可有可无,没有的时候匹配hel
    6 ['hel']

    *  表示*前面一个字符或组的重复范围,范围从0开始到正无穷,[0,+∞]

    复制代码
    1 >>> str2="111111133111188211111111111134234"
    2 >>> re.findall("1*",str2)  #1*表示字符1出现0次或多次,从字符串依次匹配,如果不是1就用空补全
    3 ['1111111', '', '', '1111', '', '', '', '111111111111', '', '', '', '', '', '']
    4 >>> re.findall("11*",str2)  #11*表示第二个字符1出现0次或多次,第一个字符1已经固定
    5 ['1111111', '1111', '111111111111']
    复制代码

    +  类似与*,表示+前面一个字符或组的重复范围,范围从1开始到正无穷,[1,+∞]

    1 >>> re.findall("11+",str2)  #11+表示第二个1必须是出现1次或多次
    2 ['1111111', '1111', '111111111111']
    3 >>> re.findall("1+",str2)  #1+表示必须出现一次1及以上
    4 ['1111111', '1111', '111111111111']
    

    {}  {n,m},指定范围,不指定m表示从n到无穷,只有一个n是只能是这么多次

    复制代码
    1 >>> str2="111111133111188211111111111134234"  
    2 >>> re.findall("1{4}",str2)  #按照字符1重复4次匹配,共匹配成功5次
    3 ['1111', '1111', '1111', '1111', '1111']
    4 >>> re.findall("3{2}",str2)  #匹配出现2次3的字符串
    5 ['33']
    6 >>> re.findall("3{1,3}",str2)  #匹配出现1到3次3的情况
    7 ['33', '3', '3']
    8 >>> re.findall("1{1,}",str2)  #匹配出现1至少一次的情况 
    9 ['1111111', '1111', '111111111111']
    复制代码

    转义字符

      反斜杠后边跟元字符去除特殊功能,反斜杠后边跟普通字符实现特殊功能

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

    字符串:包含特殊字符、数字、大小写字母及汉字

    1 >>> str3='123456  7890@#$abcd  efg!%&*HIJKLMN陈'

    d  匹配十进制数

    1 >>> re.findall("d",str3)
    2 ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']

    D  匹配非数字字符

    1 >>> re.findall("D",str3)
    2 [' ', ' ', '@', '#', '$', 'a', 'b', 'c', 'd', ' ', ' ', 'e', 'f', 'g', '!', '%', '&', '*', 'H', 'I', 'J', 'K', 'L', 'M', 'N', '陈']

    s  匹配任何空白字符

    >>> re.findall("s",str3)
    [' ', ' ', ' ', ' ']

    S  匹配任何非空白字符

    1 >>> re.findall("S",str3)
    2 ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '@', '#', '$', 'a', 'b', 'c', 'd', 'e', 'f', 'g', '!', '%', '&', '*', 'H', 'I', 'J', 'K', 'L', 'M', 'N', '陈']

    w  匹配任何字母数字汉字字符

    1 >>> re.findall("w",str3)
    2 ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'H', 'I', 'J', 'K', 'L', 'M', 'N', '陈']

    W  匹配任何非字母数字汉字字符

    1 >>> re.findall("W",str3)
    2 [' ', ' ', '@', '#', '$', ' ', ' ', '!', '%', '&', '*']

      匹配一个特殊的字符边界,注意:因为和py解释器有冲突,所以需要加上r表示以源生字符方式传送给re模块解释

    1 >>> re.findall(r"abcd",str3)
    2 ['abcd']
    3 >>> re.findall(r"123456",str3)
    4 ['123456']

    源生字符r示例1:匹配“abcle”中的‘cl’,l无特殊含义

    复制代码
     1 >>> import re
     2 >>> str4="abcle"
     3 >>> re.findall('cl','abcle')    #报错,py解释器会解释一次转义字符,一个无法解释
     4 >>> re.findall('c\l','abcle')    #报错,py解释器将两个解释成一个传给re模块,re模块
    5 >>> re.findall('c\l','abcle')  #py解释器将三个解释成\传给re模块,re模块解释\转义匹配cl 6 ['c\l']    #因为匹配出来的cl的是特殊字符,所以py解释器将转义一次输出 7 >>> re.findall('c\\l','abcle')  #py解释器将第一个和第二个解释成一个,第三个第四个解释成一个,共两个传给re模块 8 ['c\l'] 9 >>> re.findall(r'c\l','abcle')  #py解释器通过r标识,将两个解释为源生字符直接传给re模块 10 ['c\l']
    复制代码

    源生字符r示例2:匹配“abce”中的‘c’,有特殊含义,为ascii表的退格

    复制代码
     1 >>> str5="abce"
     2 >>> re.findall('c','abce')
     3 ['cx08']
     4 >>> re.findall('c\b','abce')
     5 ['c']
     6 >>> re.findall('c\','abce')
     7 ['cx08']
     8 >>> re.findall('c\\b','abce')
     9 []
    10 >>> re.findall(r'c','abce')
    11 ['c']
    12 >>> re.findall(r'c\b','abce')
    13 []
    14 >>> re.findall(r'c\','abce')
    15 []
    16 >>> re.findall(r'c\\b','abce')
    17 []
    18 >>> re.findall(r'c',r'abce')
    19 ['c']
    20 >>> re.findall(r'c\b',r'abce')  #当字符串内有特殊含义的字符时候,需要加r转义为源生字符
    21 ['c\b']
    22 >>> re.findall(r'c\',r'abce')
    23 ['c\']
    24 >>> re.findall(r'c\\b',r'abce')
    25 []
    复制代码

    ()  分为普通分组和命名分组两种,和的意思,匹配规则的字符串以组的方式划成一个整体,这个整体赋规则匹配字符串

    1 >>> str6="faefhuknghellohellohelloafeahelloadf"
    2 >>> re.findall("(hello)+",str6)  #将hello组成一个整体进行+规则
    3 ['hello', 'hello']  #因为优先级的限制,只能显示分组内的内容
    4 >>> re.findall("(?:hello)+",str6)
    5 ['hellohellohello', 'hello']  #?:是一个格式,取消优先级限制,将匹配到的所有显示出来

    分组一般配合re.search()和re.match()方法调用

    re.search()格式和findall相同,但是其返回的是一个对象,通过调用对象的group方法返回具体的值,re.search()只会匹配一次值,匹配到之后将不再向后匹配,即只有一个结果。

    1 >>> re.search("(hello)+",str6)
    2 <_sre.SRE_Match object; span=(9, 24), match='hellohellohello'>
    3 >>> ret=re.search("(hello)+",str6)
    4 >>> ret.group()
    5 'hellohellohello'

    re.match()方法和元字符^的功能类似,匹配字符串开头,返回一个对象,并且也能通过group方法返回具体的值

    复制代码
    1 >>> str7="hellohellohellonameafeahelloadf"
    2 >>> ret=re.match("(hello)+",str7)  #开头有hello能匹配到
    3 >>> ret.group()
    4 'hellohellohello'
    5 >>> ret=re.match("(name)+",str7)  #开头没有name,匹配不到
    6 >>> ret.group()
    7 Traceback (most recent call last):
    8   File "<stdin>", line 1, in <module>
    9 AttributeError: 'NoneType' object has no attribute 'group'
    复制代码

    命名分组:在分组的基础上加上一个名字,通过group方法调用分组名字返回具体的值

    复制代码
    1 >>> str8="-blog-aticles-2015-04"
    2 >>> ret=re.search(r"-blog-aticles-(?P<year>d+)-(?P<month>d+)",str8)  #?P是定义命名的格式,<>内是名字
    3 >>> ret.group('year')
    4 '2015'
    5 >>> ret.group('month')
    6 '04'
    复制代码

    []  字符集,中括号内的字符集合,关系为或,即匹配括号内任意一个字符即可,字符集内的-^三个字符具有特殊意义,其他字符丧失原来的特殊意义。

    1 >>> str9="adf13415aggae8657dfc" 
    2 >>> re.findall("a[dg]+",str9)  #匹配a开头,后面多余一个d或者g结尾的部分
    3 ['ad', 'agg']

    字符集内的-表示一个范围

    1 >>> re.findall("[0-9]+",str9)  #包含0-9数字的字符,匹配+规则
    2 ['13415', '8657']
    3 >>> re.findall("[a-z]+",str9)
    4 ['adf', 'aggae', 'dfc']

    字符集内的^表示取反

    1 >>> re.findall("[^a-z]+",str9)  #不是包含a-z字母的字符,匹配+规则
    2 ['13415', '8657']
    3 >>> re.findall("[^0-9]+",str9)
    4 ['adf', 'aggae', 'dfc']

    字符集内的表示转义

    1 >>> re.findall("[d]",str9)
    2 ['1', '3', '4', '1', '5', '8', '6', '5', '7']
    3 >>> re.findall("[w]",str9)
    4 ['a', 'd', 'f', '1', '3', '4', '1', '5', 'a', 'g', 'g', 'a', 'e', '8', '6', '5', '7', 'd', 'f', 'c']

    |  管道符号,表示或

    1 >>> str10="www.oldboy.com;www.oldboy.cn;www.baidu.com;"
    2 >>> re.findall("www.(?:w+).(?:com|cn)",str10)
    3 ['www.oldboy.com', 'www.oldboy.cn', 'www.baidu.com']

    贪婪匹配和非贪婪匹配(基于重复)

    贪婪匹配:按照最长的结果匹配

    1 >>> str11="dasa11s6666dabccccasd"
    2 >>> re.findall("abc+",str11)  #+表示从范围从1到正无穷,所以多少个c都可以匹配到
    3 ['abcccc']
    4 >>> re.findall("d+",str11)
    5 ['11', '6666']

    非贪婪匹配:按照最短的结果匹配

    1 >>> re.findall("d+?",str11)  #在+后面加?表示取最小范围1
    2 ['1', '1', '6', '6', '6', '6']
    3 >>> re.findall("abc+?",str11)
    4 ['abc']

    非贪婪应用示例:

    1 >>> str12="<div>yuan<img></div><a href=""></div>"
    2 >>> re.findall("<div>.*?</div>",str12)  #匹配到第一个</div>
    3 ['<div>yuan<img></div>']

    非贪婪匹配规则:

    1 *? 重复任意次,但尽可能少重复
    2 +? 重复1次或更多次,但尽可能少重复
    3 ?? 重复0次或1次,但尽可能少重复
    4 {n,m}? 重复n到m次,但尽可能少重复
    5 {n,}? 重复n次以上,但尽可能少重复

    .*?用法:

    1 . 是任意字符
    2 * 是取 0 至 无限长度
    3 ? 是非贪婪模式。
    4 合在一起就是取尽量少的任意字符,一般不会这么单独写,他大多用在:“.*?a”,就是取前面任意长度的字符,到最后一个 a 出现

    re模块方法

    re.findall()方法:匹配所有,将匹配到的结果全部按照列表方式返回

    re.search()方法:返回一个对象,通过group方法调用具体值,示例见分组部分,匹配到第一个就不再往下继续匹配了,没匹配到返回一个None

    re.match()方法:只在字符串开始的位置匹配,返回的是一个对象,通过group方法调用具体值,示例见分组部分

    re.split()方法:分割,以列表方式返回,中间用正则模糊匹配,可以限定分割次数

    复制代码
    1 >>> str13="hello23world12my7name"
    2 >>> re.split("d+",str13)  #以数字为分割线,返回其他值
    3 ['hello', 'world', 'my', 'name']
    4 >>> re.split("(d+)",str13)  #同时返回分割线
    5 ['hello', '23', 'world', '12', 'my', '7', 'name']
    6 >>> re.split("d+",str13,1)  #分割一次
    7 ['hello', 'world12my7name']
    复制代码

    特殊情况,分割出空

    1 >>> re.split("l","hello bob")
    2 ['he', '', 'o bob']

    re.sub()方法:替换,格式为:规则-替换内容-字符串-计数限定次数

    复制代码
    1 >>> str14="hello 123 123 name world my name "
    2 >>> re.sub("d+","A",str14)
    3 'hello A A name world my name '
    4 >>> re.sub("d","A",str14)
    5 'hello AAA AAA name world my name '
    6 >>> re.sub("d","A",str14,3)
    7 'hello AAA 123 name world my name '
    复制代码

    re.subn():类似于sub,但是以元组返回,并且返回替换次数

    1 >>> re.subn("d","A",str14,3)
    2 ('hello AAA 123 name world my name ', 3)

    re.finditer():返回一个迭代器,调用也是要group方法

    复制代码
    1 >>> ret=re.finditer("d+","dasfjk324khk4234kj234hkj234hkj234kj234k2j34hk2j3h4")
    2 >>> print(ret)
    3 <callable_iterator object at 0x000001CE69609470>
    4 >>> print(next(ret))
    5 <_sre.SRE_Match object; span=(6, 9), match='324'>
    6 >>> print(next(ret).group())  #因为已经迭代了一次,所以返回第二个值
    7 4234
    复制代码

    re.compile():编译规则,以编译对象的方式调用,频繁调用同一个规则时候使用

    1 >>> num_rule=re.compile('d+')
    2 >>> print(num_rule,type(num_rule))
    3 re.compile('\d+') <class '_sre.SRE_Pattern'>
    4 >>> num_rule.findall("hello 123 3241")
    5 ['123', '3241']
  • 相关阅读:
    非常抱歉,全站内容审核中...
    jS代码总结(2)
    timestamp(数据库中的数据类型)
    jS代码总结(1)
    TextWriterTraceListener 和设计时属性支持文件xmta
    validating和validated的区别
    IoC和控制反转
    wince BindingSource
    简单网络传递加密数据
    C#不对称加密
  • 原文地址:https://www.cnblogs.com/chenqizhou/p/7117478.html
Copyright © 2011-2022 走看看