re模块

 

正则表达式、re模块

 

正则表达式

 

    • 正则表达式就是字符串匹配的一种规则。
    • 用途:
      1. 使用一些规则来检测字符串是否符合内容
      2. 使用一些规则从内容中找到符合要求的内容。  
    • 字符组:在同一位置可能出现的各种字符组成了一个组。在正则式中用[ ]表示

 字符:

    • 注意事项:
      1. 如果两个表达式之间用或来连接,且有一部分正则规则相同,要把规则长的放到前面。例如匹配15位身份证或者18位身份证,要把18位的正则表达式放到前面。
      2. 如果对一组正则表达式的整体进行两次约束,就将这一组表达式分成一个组,在组外进行两次约束。    


   量词

元字符 匹配内容
. 匹配除换行符以外的任意字符
\w 匹配字母、数字、下划线
\W 匹配非字母、非数字、非下划线
\d 匹配数字
\D 匹配非数字
\s 匹配任意的空白符
\S 匹配非空白符
^ 匹配字符串的开始
$ 匹配字符串的结尾
a|b 匹配字符a或者b
() 匹配括号内的表达式,也表示一个组
[^...] 匹配除了字符组中字符的所有字符
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词的结尾

 

  • [^...]:匹配除了字符组中的所有字符:例

 

 

    • 贪婪匹配与惰性匹配
      • 前面的*+?以及{n,m}都是贪婪匹配,都是尽可能多的匹配。
      • 而在后面加个“?”,就会变成惰性匹配,尽可能少的匹配。  

 

知识点补充:

    贪婪匹配的回溯机制:先尽可能的匹配到最后,然后往回查找,一直到最先找到的匹配符为止。尽可能多的匹配。

    惰性机制:找到第一个终止符就停止。尽可能少的匹配。

 

  •  .*?的用法  

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

 

  •  re模块的用法

    • re.findall(正则表达式,待匹配的字符串)

 

import re

ret = re.findall('a', 'eva egon yuan')  # 返回所有满足匹配条件的结果,放在列表里
print(ret) #结果 : ['a', 'a']  :存放跟正则匹配的所有结果

总结:findall返回一个列表,包含所有的结果。

 

 

    • re.search(正则表达式,待匹配的字符串)

 

      • 匹配成功一次停止匹配,并返回这个正则结果对象。匹配不到返回None。

      • 如果匹配到了,就返回一个正则结果的对象,查看结果用xx.group()查看结果。 

 

    • re.match(正则表达式,带匹配的字符串)

      • 默认在正则表达式前面加了一个“^”,匹配以XX开头的字符。

      • 匹配成功一次就停止匹配,并返回这个正则结果的对象,匹配不到返回None;

      • 查看结果用group()查看。  

    • re.sub(正则表达式,要替换成的字符串,待匹配的字符串,替换次数(默认全部替换))   

ret = re.sub('\d.', 'H', 'eva3egon4yuan4', 1)#将数字及数字后面的除换行符之外的字符替换成'H',参数1表示只替换1个
print(ret) #evaHgon4yuan4
    • re.subn(正则表达式,要换成的字符,待匹配的字符串) 

msg = re.subn("\d.","liqing","sadjaskjd13123ajs")
print(msg)  ##('sadjaskjdliqingliqingliqingjs', 3)  返回值是一个元祖,分别放有替换结果以及替换的次数。
    • re.compile(正则表达式)  

 

obj = re.compile("\d..")     ##  编译:在多次执行同一个正则表达的时候使用,可以节省编译时间,提高匹配效率。创建一个编译模板。
ret1 =obj.findall("1235asd1341ddas")
ret2 = obj.match("1235asd1341ddas")
print(ret1)   #['123', '5as', '134', '1dd']
print(ret2.group())    #123

 

    • re.finditer(正则表达式,带匹配的字符串) :适用于结果比较多的情况,可以有效节省内存空间,

import re
ret = re.finditer('\d', 'ds3sy4784a')   
print(ret)                         # <callable_iterator object at 0x10195f940>#返回一个迭代器
print(ret.__next__())              #<_sre.SRE_Match object; span=(2, 3), match='3'>
print(ret.__next__().group())
print(ret.__next__().group())
或者:
for i in ret: print(i.group()) print(next(ret).group()) #查看第一个结果 print(next(ret).group()) #查看第二个结果 print([i.group() for i in ret]) #查看剩余的所有结果 ['7', '8', '4'],
    • findall的优先级查询()   
ret1 = re.findall("www.(taobao|baidu).com","www.taobao.com")
print(ret1)  #['taobao']在findall中,会优先显示组内匹配到的内容。
ret2 = re.findall("www.(?:taobao|baidu).com","www.taobao.com")
print(ret2)   #['www.taobao.com']如果想取消分组优先效果,在组内开始的时候加上?:
    • split的优先级查询  
import re
ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']split分割一个字符串,默认被匹配到的分隔符不会出现在结果列表中
ret=re.split("(\d+)","eva162784673egon44yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']  如果将匹配的正则放到组内,就会将分隔符放到结果列表里

 

  • 拓展

    • 匹配标签

        • 给分组命名。    
1 import re
2 ret = re.search('<(?P<yb>\w+)>(?P<baby>\w+)</(?P=yb)>',"<waha3>hello</waha3>")  #定义?P<分组的名字>
3 print(ret.group("yb")) #waha3  查找分组名字为“yb”的匹配结果
4 print(ret.group("baby"))#hello  查找分组名字为baby的匹配结果
5 print(ret.group())  #<waha3>hello</waha3>    #search中没有分组优先的概念。
        • 给分组编号。      
import re
ret = re.search(r"<(\w+)>(\w+)</\1>","<python>hello</python>")
#如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致
#获取的匹配结果可以直接用group(序号)拿到对应的值
print(ret.group())   #结果 :<python>hello</python>
print(ret.group(0))  #结果 :<python>hello</python>  序号0对应的值就是匹配的结果
print(ret.group(1))  #结果 :python
print(ret.group(2))  #结果 :hello

 资料补充:https://www.cnblogs.com/wxshi/p/6827056.html

 

 

      

   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2018-04-28 17:26  弃疾  阅读(80)  评论(0)    收藏  举报

导航