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
    无限的我,现在才开始绽放,从东边的第一缕阳光到西边的尽头
  • 相关阅读:
    web前端要学哪些?
    angularjs factory,service,provider 自定义服务的不同
    PSP软件开发过程
    Eclipse连接sqlserver体验过程
    在线制作GIF图片项目愿景与范围
    C# Hashtable vs Dictionary 学习笔记
    Unity 工作经历+近期面试经历
    配置文件加载的一个坑
    rabbitmq exchange type
    centos7下nginx添加到自定义系统服务中提示Access denied
  • 原文地址:https://www.cnblogs.com/huangqihui/p/9438120.html
Copyright © 2011-2022 走看看