• python之正则表达式及RE模块


    正则表达式(匹配字符串)
    web界面正则匹配工具:
    http://tool.chinaz.com/regex/

    元字符

    复制代码
     1 .   匹配除换行符之外的任意字符
     2 w  匹配数字字母下划线
     3 d  匹配数字
     4 	  匹配制表符
     5 
      匹配换行符
     6 s  匹配空白符(包含,空格,制表符和换行符)
     7   单词的边界
     8 W  匹配非数字字母下划线
     9 S  匹配非空白符
    10 D  匹配非数字
    11 ^       匹配开始符
    12 $       匹配结束符
    13 |       或者,如果是有包含关系的,长的放左边
    14 []      匹配字符组,具体的范围
    15 [^...]  匹配非字符组中的字符
    16 ()      匹配括号内的是一组
    17 
    18 
    19 转义符
    20 如果在测试工具中测试正常的代码拿到python中,由于转义符的问题搞不定,那么就直接在字符串外面+r
    21 print('\\n')
    22 print('\n')
    23 print(r'\n')
    24 print(r'
    ')
    25 
    26 事例:
    27 www.(baidu|google).com
    28 [0-9] == [0123456789] #表示0到9的所有数
    29 [a-z]/[A-Z]     表示a到z/A-Z所有英文字母
    30 [A-Za-z0-9]     表示数字和大小写字母
    31 
    32 
    33 量词
    34 贪婪匹配: 尽可能多的匹配(默认模式)
    35 {n}     匹配n次
    36 {n,}    匹配至少n次至多无限次
    37 {n,m}   匹配至少n次至多m次
    38 *       匹配前面字符0次或多次
    39 +       匹配前面字符1次或多次
    40 非贪婪/惰性匹配
    41 ?       匹配前面字符0次或1次(.*?)
    42 abbbx   正则^ab+?x,如果正则是^ab+?结果则是ab
    43 
    44 
    45 总结
    46 正则表达式: 不仅仅要能匹配出对的,还要尽量避免匹配错误的,提高精准度
    47 分组的作用: 分组也可以和量词连用,表示这一个组遵循某个量词的约束
    48 
    49 常用的非贪婪匹配
    50 *?      重复任意次,但尽可能少重复
    51 .*?     匹配前边任意字符,尽可能少的匹配
    52 +?      重复1次或更多次,但尽可能少重复
    53 ??      重复0次或1次,但尽可能少重复
    54 .?x     取尽量少的任意字符,直到一个x出现
    复制代码

    re的功能是在python中执行正则表达式
    re模块下的常用方法
    import re
    re.findall  正则 待匹配字符串,列表,所有符合的项
    re.search    变量.group取结果,只有一项结果
    re.match     变量.group取结果,默认在正则之前加上^
    re.finditer 把匹配的结果存放在迭代器中

    re.findall('正则表达式','带匹配的字符')

    复制代码
     1 re.findall('正则表达式','带匹配的字符')
     2 ret = re.findall('d+','aaa83bbb38')
     3 print(ret)
     4 结果
     5 ['83', '38']
     6 事例2
     7 ret = re.findall('d','aaa83bbb38')
     8 print(ret)
     9 结果
    10 ['8', '3', '3', '8']
    11 
    12 # ?:把括号python中的分组变成了原来正则表达式中的分组
    13 lst = re.findall(r"a(?:d+)c", "a123456c")
    14 l2 = re.findall(r"a(d+)c", "a123456c") 
    15 print(lst)
    16 print(l2)
    17 结果
    18 ['a123456c']
    19 ['123456']
    复制代码

    re.finditer()   #返回一个存放匹配结果的迭代器,节省空间

    复制代码
     1 ret = re.finditer('d+','linux83admin60yuan25')
     2 print(ret)                  #直接打印返回的是一个迭代器
     3 print(next(ret).group())    #查看第1个结果
     4 for r in ret:               #查看剩余的结果
     5     print(r.group())
     6 结果
     7 <callable_iterator object at 0x000001FF0EACEBA8>
     8 83
     9 60
    10 25
    复制代码

    search 搜索, 查找
    一旦匹配到结果,直接返回,如果匹配不到结果,返回None

    复制代码
     1 ret = re.search('d','aaa83bbb38')
     2 print(ret)          #返回的匹配结果,而不是具体的值
     3 print(ret.group())  #从左到右找到第一个匹配的取出
     4 结果
     5 <_sre.SRE_Match object; span=(4, 5), match='8'>
     6 8
     7 
     8 ret = re.search('d+','aaa83bbb22')
     9 print(ret.group())
    10 结果
    11 83
    复制代码

    match匹配,从头开始匹配,相当于在你正则前面加了一个^

    复制代码
    1 ret = re.match('d+','83aaa222bbb38')
    2 print(ret.group())
    3 等于
    4 ret = re.search('^d+','83aaa222bbb38')
    5 print(ret)
    6 结果
    7 83
    复制代码

    search和match的区别:
    search查找,找到了结果就返回
    match,从头开始匹配

    给分组正则匹配定义一个名字(?P<名字>正则表达式)

    1 ret = re.finditer(r'姓名:(?P<name>.*?),地址:(?P<address>.*?),','姓名:bob,地址:迪拜,年龄:18')
    2 for i in ret:
    3     print(i.group('name'),i.group('address'))
    4 结果
    5 bob 迪拜

    re.split():分割

    1 st = 'linux83admin60yuan25test'
    2 ret = re.split('d+',st)     #按照一个或多个数字进行分割
    3 print(ret)
    4 结果
    5 ['linux', 'admin', 'yuan', 'test']

    sub用正则替换

    1 s = 'linux83admin60yuan25'
    2 ret  = re.sub('d+','_|_',s,1)  #将一个或多个数字替换为_|_,1表示只替换1个,以字符串形式返回
    3 print(ret)
    4 结果
    5 linux_|_admin60yuan25

    subn显示替换次数

    1 ret  = re.subn('d+','_|_',s)  #将一个或多个数字替换为_|_,以元组形式返回
    2 print(ret)
    3 结果
    4 ('linux_|_admin_|_yuan_|_', 3)

    re.compile():编译后引用正则匹配(返回列表)

    1 ret = re.compile('d+') #将正则编译成一个正则对象,匹配一个或多个数字
    2 lst = ret.findall('linux83admin60yuan25')
    3 print(lst)
    4 在多次执行同一个正则表达式的时候compile事先编译

    案例:爬取电影天堂

    复制代码
     1 import re
     2 from urllib.request import urlopen
     3 
     4 content = urlopen("https://www.dytt8.net/html/gndy/dyzz/20181228/57986.html").read().decode("gbk")
     5 # print(content)
     6 
     7 reg = r'<div id="Zoom">.*?片  名(?P<name>.*?)<br />◎年  代(?P<years>.*?)<br />.*?◎上映日期(?P<date>.*?)<br />'+ 
     8 '.*?◎主  演(?P<main>.*?)◎简  介.*?<td style="WORD-WRAP: break-word" bgcolor="#fdfddf"><a href="(?P<download>.*?)">'
     9 
    10 it = re.finditer(reg, content, re.S)    # re.S 去掉.里面的
    
    11 
    12 for el in it:
    13     print(el.group("name"))
    14     print(el.group("years"))
    15     print(el.group("date"))
    16     print(el.group("main").replace("<br />      ", ", "))
    17     print(el.group("download"))
    18 
    19 结果
    20  黄金兄弟 / 新古惑仔 / 新版古惑仔 / 黄金七十二小时 
    21  2018 
    22  2018-09-20(中国香港) / 2018-09-21(中国) 
    23  郑伊健 Ekin Cheng , 陈小春 Jordan Chan , 谢天华 Michael Tse , 钱嘉乐 Kar Lok Chin , 林晓峰 Jerry Lamb , 曾志伟 Eric Tsang , 佘诗曼 Charmaine Sheh , 张雅玫 Yamei Zhang <br /><br />
    24 ftp://ygdy8:ygdy8@yg45.dydytt.net:8373/阳光电影www.ygdy8.com.黄金兄弟.BD.720p.粤语中字.mkv
    复制代码

    其他

    复制代码
     1 事例1
     2 ret = re.findall(r'd+(.d+)?','2.34+666.87')
     3 print(ret)
     4 结果
     5 ['.34', '.87']
     6 #d+ = 2    (.d+) = .34
     7 #d+ = 666  (.d+) = .87
     8 #findall 优先显示分组中匹配到的内容
     9 
    10 #如果想匹配浮点数就要把默认的非婪模式改为?:贪婪模式
    11 ret = re.findall(r'd+(?:.d+)?','2.34+666.87')
    12 print(ret)
    13 结果
    14 ['2.34', '666.87']
    15 
    16 
    17 事例2
    18 ret = re.findall('www.(?:baidu|google).com','www.baidu.com')
    19 print(ret)
    20 结果
    21 ['www.baidu.com']
    22 
    23 ret = re.findall('www.(baidu|google).com','www.baidu.com,www.google.com')
    24 print(ret)
    25 结果
    26 ['baidu', 'google']
    27 
    28 
    29 ()组事例
    30 ret = re.search('(www).(baidu|google).(com)','www.baidu.com,www.google.com')
    31 print(ret)
    32 print(ret.group())
    33 print(ret.group(0))
    34 print(ret.group(1))
    35 print(ret.group(2))
    36 print(ret.group(3))
    37 结果
    38 <_sre.SRE_Match object; span=(0, 13), match='www.baidu.com'>
    39 www.baidu.com
    40 www.baidu.com
    41 www
    42 baidu
    43 com
    复制代码
  • 相关阅读:
    线程同步(一)
    java守护线程
    C/C++中如何获取数组的长度?
    java操作xml方式比较与详解(DOM、SAX、JDOM、DOM4J)
    按单词逆序句子(含标点)
    常见误区(一)
    java创建XML及开源DOM4J的使用
    C++学习(一)
    java读XML文件
    MiniProfiler 兼容 Entity Framework 6
  • 原文地址:https://www.cnblogs.com/q455674496/p/10208694.html
Copyright © 2020-2023  润新知