zoukankan      html  css  js  c++  java
  • python: re模块

      Python中可以使用正则表达式, Python提供re模块,包含所有正则表达式的功能。由于Python的字符串本身也用转义,所以要特别注意:在字符串的前面加上 r 的前缀, 就不用考虑转义的问题了.

    s1 = 'djioi
    djj'  # 
     表示换行
    print(s1)
    # djioi
    # djj
    
    s2 = r'djioi
    djj'  # 字符串前加个r 就不用考虑转义的问题了.
    print(s2)  # djio

      python的re模块提供了很多种有关正则表达式的方法

    一 . 匹配

    1. findall

      语法 :   re.findall('正则表达式', '字符串')

    import re
    ret = re.findall('d+', '19874ashfk0248')  # 匹配数字,数字的长度至少为1
    print(ret)  # 返回值为列表
    # ['19874', '0248']

      当正则表达式里有分组()时, 会优先显示分组里匹配的字符串,无论分组有没有匹配到,没有匹配到则为空字符串' ', 可以在分组里的第一个位置加上 '?:' ,就会取消分组的优先显示特权.

    ret2 = re.findall('d+(w+)', '19874ashfk0248')
    print(ret2)  # ['ashfk0248']
    
    ret3 = re.findall('(-)?d+', '78543')
    print(ret3)  # ['']

    ret2 = re.findall('d+(?:w+)', '19874ashfk0248')  # 在分组里加入 ?:
    print(ret2)  # ['19874ashfk0248']
    
    ret3 = re.findall('(?:-)?d+', '78543')
    print(ret3)  # ['78543']
     

    2. search

      语法 :   search('正则表达式', '字符串')

    ret1 = re.search('d+', '19874ashfk0248')
    print(ret1)  # <re.Match object; span=(0, 5), match='19874'>
    print(ret1.group())  # 19874
    ret3 = re.search('d', 'shuyuiiuus')
    print(ret3)  # None     没有匹配上的字符时,会返回None
    # print(ret3.group())  #  报错: 'NoneType' object has no attribute 'group'
     

      当正则表达式里有分组()时,group()可以传数字来显示第几个分组匹配的值, 数字为0或没有时,表示显示匹配所有的值.

    ret2 = re.search('(d+)(w+)(d+)', '19874ashfk0248')
    print(ret2.group())  # 19874ashfk0248
    print(ret2.group(0))  # 19874ashfk0248
    print(ret2.group(1))  # 19874
    print(ret2.group(2))  # ashfk024
    print(ret2.group(3))  # 8

    3. match

      语法 :  re.match('正则表达式', '字符串')

    ret1 = re.match('d+', '786jhg032')
    print(ret1)  # <re.Match object; span=(0, 3), match='786'>
    print(ret1.group())  # 786
    
    ret2 = re.match('d+', 'kt786jhg032')  
    # 字符串的第一个不是数字,match里的正则表达式自带开始符: ^ ,所以字符串的第一个字符必须是数字才能匹配上.
    print(ret2)  # None
    # print(ret2.group())  # 报错: 'NoneType' object has no attribute 'group'

    4. finditer

      语法 : re.finditer('正则表达式', '字符串')

    ret1 = re.finditer('d+', '786jhg032te654')  # ret1是个迭代器
    print(ret1)  # <callable_iterator object at 0x000001208AF38AC8>
    print(ret1.__next__().group())  # 786
    print(ret1.__next__().group())  # 032
    print(ret1.__next__().group())  # 654

    总结 findall, search, match, finditer 的区别 :

      findall : 在string中查找所有 匹配成功的组, 即用括号括起来的部分, 返回list对象, 每个列表元素是由每个匹配的所有组组成的list.

      search : 在string中进行搜索,成功返回object, 失败返回None, 只匹配一个

      match : 匹配string 开头,成功返回object, 失败返回None只匹配一个

      finditer : 在string中查找所有 匹配成功的字符串, 返回iterator,每个元素是一个object。

    二. 替换

    1. sub

      语法 : re.sub('正则表达式',  '替换的元素', '字符串', 次数)

    ret1 = re.sub('d+', 'h', 'dguj23kk321jjjj222kkkk111', 2)  # 把字符串里匹配到的的数字替换成 'h', 只替换2次
    print(ret1)  # dgujhkkhjjjj222kkkk111
    ret2 = re.sub('d+', 'h', 'dguj23kk321jjjj222kkkk111')  # 没有替换次数,默认全部替换
    print(ret2)  # dgujhkkhjjjjhkkkkh

    2. subn

      语法 : re.subn('正则表达式',  '替换的元素', '字符串', 次数)

    ret3 = re.subn('d+', 'd', 'hhd3567fg8er590ggg0mmm345')  # subn会返回替换的次数
    print(ret3)  # ('hhddfgderdgggdmmmd', 5)
    ret4 = re.subn('d+', 'd', 'hhd3567fg8er590ggg0mmm345', 3)  
    print(ret4)  # ('hhddfgderdggg0mmm345', 3)

    三. 切割

      split 语法 :  re.split('正则表达式', '字符串')

    s = 'qwerty'
    lst = s.split('qwerty')
    print(lst)  # ['', '']
    
    re1 = re.findall('d+', 'dyudkd34hudslwio987hud22aokd')
    print(re1)  # ['34', '987', '22']
    ret1 = re.split('d+','dyudkd34hudslwio987hud22aokd')
    print(ret1)  # ['dyudkd', 'hudslwio', 'hud', 'aokd']
    
    
    re2 = re.findall('d+w+', '19874ashfk0248')
    print(re2)  # ['19874ashfk0248']
    ret2 = re.split('d+w+', '19874ashfk0248')  
    # 匹配到的字符串'19874ashfk0248' 对 源字符串'19874ashfk0248'进行切割,得到两个空字符串
    print(ret2)  # ['', '']
    #
    #
    re3 = re.findall('d+(w+)', '19874ashfk0248')  
    print(re3)  # ['ashfk0248']
    ret3 = re.split('d+(w+)', '19874ashfk0248')
    # 正则表达式里有分组时,把匹配的字符串对原字符串切割后,还要显示分组里匹配到的字符串
    print(ret3)  # ['', 'ashfk0248', '']
    #
    #
    re4 = re.findall('d+(?:w+)', '19874ashfk0248')
    print(re4)  # ['19874ashfk0248']
    ret4 = re.split('d+(?:w+)', '19874ashfk0248')
    print(ret4)  # ['', '']

    四.进阶方法

    1. finditer

      re.finditre获得的是一个迭代器,取值时节省内存,提高空间效率

    2. complie

      使用re的一般步骤是先将正则表达式的字符串形式通过complie编译为一个实例对象,然后使用这个实例对象处理文本并获得匹配结果.我们在多次使用一个正则表达式时,complie会帮我们节省很多时间.

      语法 : re.complie('正则表达式') 

    ret = re.compile('d+')
    ret1 = ret.findall('1234')
    ret2 = ret.search('qwer')
    print(ret1)  # ['1234']
    print(ret2)  # None  没有匹配到字符,返回None

    五. 分组练习

    # 把所有的数字给取出来
    ret1 = re.findall('-?d+(?:.d+)?', "1-2*(60+(-40.35/5)-(-4*3))")
    print(ret1)  # ['1', '-2', '60', '-40.35', '5', '-4', '3']
    
    # 把所有整数取出来
    ret2 = re.findall('d+(?:.d+)|(d+)', '1-2*(60+(-40.35/5)-(-4*3))')
    print(ret2)  # ['1', '2', '60', '', '5', '4', '3']
    ret2.remove('')
    print(ret2)  # ['1', '2', '60', '5', '4', '3']
    
    # 把'<a>wahaha<a>'里的wahaha取出来
    ret3 = re.findall('>(w+)<', r'<a>wahaha<a>')
    print(ret3)  # ['wahaha']
    
    # r'<(w+)>(w+)</(w+)>'  r'<(a)>(w+)</a>'
    ret4 = re.search(r'<(w+)>(w+)</(w+)>', r'<a>wahaha</a>')
    print(ret4.group())  # <a>wahaha</a>
    
    # 分组命名 : ?P
    
    # #                       r'<(w+)>(w+)</(w+)>'
    ret1 = re.search(r'<(?P<name>w+)>(w+)</(?P=name)>', r'<a>wahaha</a>')
    # 把第一个分组的名字命为name, 两对尖角符<>之间的名字必须一样
    print(ret1.group())   # <a>wahaha</a>
    print(ret1.group('name'))  # a   通过对group方法传分组名字的参数,来获取分组所匹配的字符
    
    #                 r"<(w+)>w+</1>"
    ret2 = re.search(r'<(w+)>(w+)</(1)>', r'<a>wahaha</a>')
    # 1是默认为和第一个分组名字一样
    print(ret2.group())   # <a>wahaha</a>
    print(ret2.group(1))  # a

     六. 爬虫练习

    # 爬取豆瓣评分前250名电影的信息
    import re
    from urllib.request import urlopen
    # 内置的包 来获取网页的源代码 字符串
    # res = urlopen('http://www.cnblogs.com/Eva-J/articles/7228075.html')
    # print(res.read().decode('utf-8'))
    
    def getPage(url):
        response = urlopen(url)
        return response.read().decode('utf-8')
    
    def parsePage(s):   # s 网页源码
        ret = com.finditer(s)
        for i in ret:
            ret = {
                "id": i.group("id"),
                "title": i.group("title"),
                "rating_num": i.group("rating_num"),
                "comment_num": i.group("comment_num")
            }
            yield ret
    
    def main(num):
        url = 'https://movie.douban.com/top250?start=%s&filter=' % num  # 0
        response_html = getPage(url)   # response_html是这个网页的源码 str
        ret = parsePage(response_html) # 生成器
        print(ret)
        f = open("move_info7", "a", encoding="utf8")
        for obj in ret:
            print(obj)
            data = str(obj)
            f.write(data + "
    ")
        f.close()
    
    com = re.compile(
            '<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>d+).*?<span class="title">(?P<title>.*?)</span>'
            '.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>', re.S)
    count = 0
    for i in range(10):  # 一共十页
        main(count)  # count = 0
        count += 25
    无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头
  • 相关阅读:
    sublime text 4 vim 插件配置
    ssh-keygen 的使用
    distribution transaction solution
    bilibili 大数据 视频下载 you-get
    Deepin 20.2.1 安装 MS SQL 2019 容器版本
    【转】使用Linux下Docker部署MSSQL并加载主机目录下的数据库
    【转】You Can Now Use OneDrive in Linux Natively Thanks to Insync
    dotnet 诊断工具安装命令
    Linux 使用 xrandr 设置屏幕分辨率
    【转】CentOS 7.9 2009 ISO 官方原版镜像下载
  • 原文地址:https://www.cnblogs.com/huangqihui/p/9438120.html
Copyright © 2011-2022 走看看