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

    re模块和正则表达式

    正则 —— 通用的,处理 字符串
    正则表达式
    正则是一种处理文字的规则
    给我们提供一些规则,让我们从杂乱无章的文字中提取有效信息

    模块
    它只是我们使用python去操作一些问题的工具而已,和要操作的这个东西本身是两件事情

    re模块 —— python使用正则
    正则规则
    需要记忆的特别多:两大类
    测试工具http://tool.chinaz.com/regex/

    [ ]字符组
    表示在一个字符的位置可以出现的所有情况的集合就是一个字符组

    复制代码
    # 表示数字的字符组:
    # [0123456789]
    # [0-9]
    # [2-8]
    # 简写模式必须由小到大
    # 表示字母的字符组:
    # [abcd]
    # [a-z]
    # [A-Z]
    复制代码

    元字符

    复制代码
    # . 匹配除了换行符以外的任意字符
    # w 匹配字母或数字或下划线   word
    # s 匹配任意的空白符  space
    # d 匹配数字  digit
    # 
     匹配一个换行符  next
    # 	 匹配一个制表符  table
    #  匹配一个单词的结尾
    # ^ 匹配字符串的开始
    # $ 匹配字符串的结尾
    # W 匹配非字母或数字或下划线
    # D 匹配非数字
    # S 匹配非空白符
    # a|b 匹配字符a或字符b
    # () 匹配括号内的表达式,也表示一个组
    # [] 匹配字符组中的字符
    # [^]匹配除了字符组中字符的所有字符
    
    # 表示匹配任意字符:[wW][dD][sS]
    复制代码

    量词

    # * 重复零次或多次
    # + 重复一次或多次
    # ?重复零次或一次
    # {n} 重复n次
    # {n,} 重复n次或更多次
    # {n,m} 重复n到m次

    正则匹配:字符量词非贪婪标志
    字符:字符、字符组、元字符 表示一个字符位置上可以出现的内容

    匹配身份证号实例

    15位:首位不能为零,数字组成
    18位:首位不能为零,前17位是数字,最后一位可以是数字或者x

    # ^[1-9]d{14}(d{2}[0-9x])?$
    # ^([1-9]d{16}[0-9x]|[1-9]d{14})$

    r'\n' --> r' '
    在在线工具中能执行,放到python的字符串中表示成r就可以正常的执行了

    .*? 非贪婪匹配
    .*?t 遇到一个t马上停,经典用法

    re模块用法

    复制代码
    import re
    ret = re.findall('a', 'eva egon yuan')  # 返回所有满足匹配条件的结果,放在列表里,左边为正则表达式,右边为要匹配的字符串
    print(ret)  # 结果 : ['a', 'a']
    
    ret = re.search('a', 'eva egon yuan').group()
    print(ret)  # 结果 : 'a'
    # search从左到右依次找,找到一个就回来,需要使用group()获取返回值
    # 如果re.search找不到,就返回None,使用group会报错
    
    ret = re.match('a', 'abc').group()
    print(ret)
    # match从头开始配置,匹配上了需要使用group()来获取返回值
    # 匹配不上返回None,使用group会报错
    
    ret = re.split('[ab]', 'abcd')  # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割,可指定分割次数
    print(ret)  # ['', '', 'cd']
    
    ret = re.sub('d', 'H', 'eva3egon4yuan4', 1)  # 将数字替换成'H',参数1表示只替换1个
    print(ret)  # evaHegon4yuan4
    
    ret = re.subn('d', 'H', 'eva3egon4yuan4')  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
    print(ret)
    
    obj = re.compile('d{3}')  # 将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
    ret = obj.search('abc123eeee')  # 正则表达式对象调用search,参数为待匹配的字符串
    print(ret.group())  # 结果 : 123
    
    ret = re.finditer('d', 'ds3sy4784a')   # finditer返回一个存放匹配结果的迭代器
    print(ret)  # <callable_iterator object at 0x10195f940>
    print(next(ret).group())  # 查看第一个结果
    print(next(ret).group())  # 查看第二个结果
    print([i.group() for i in ret])  # 查看剩余的左右结果
    复制代码

    findall和split的优先级

    复制代码
    ret = re.findall(r'www.(baidu|oldboy).com', 'www.oldboy.com')
    print(ret)  # ['oldboy']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
    # 分组优先:优先显示括号内部的内容
    # 取消分组优先 ?:
    ret = re.findall(r'www.(?:baidu|oldboy).com', 'www.oldboy.com')
    print(ret)  # ['www.oldboy.com']
    
    ret=re.split("(d+)","eva3egon4yuan")
    print(ret)  # 结果 :['eva', '3', 'egon', '4', 'yuan']
    # 在匹配部分加上()之后所切出的结果是不同的,
    # 没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
    # 这个在某些需要保留匹配部分的使用过程是非常重要的。
    复制代码

    search分组命名和引用

    复制代码
    # 分组命名和组的引用
    ret = re.search("<(?P<tag_name>w+)>w+</(?P=tag_name)>","<h1>hello</h1>")
    # 还可以在分组中利用?<name>的形式给分组起名字
    # 获取的匹配结果可以直接用group('名字')拿到对应的值
    print(ret.group('tag_name'))  # 结果 :h1
    print(ret.group())  # 结果 :<h1>hello</h1>
    
    ret = re.search(r"<(w+)>w+</1>","<h1>hello</h1>")
    # 如果不给组起名字,也可以用序号来找到对应的组,表示要找的内容和前面的组内容一致
    # 获取的匹配结果可以直接用group(序号)拿到对应的值
    print(ret.group(1))
    print(ret.group())  # 结果 :<h1>hello</h1>
    复制代码

    匹配整数

    # 匹配整数
    ret=re.findall(r"d+.d+|(d+)","1-2*(60+(-40.35/5)-(-4*3))")
    print(ret)  # ['1', '-2', '60', '', '5', '-4', '3']
    ret.remove('')
    print(ret)  # ['1', '2', '60', '5', '4', '3']

    爬虫练习

    复制代码
    import re
    from urllib.request import urlopen
    
    def getPage(url):
        response = urlopen(url)
        return response.read().decode('utf-8')
    
    def parsePage(s):
        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)
    
        ret = com.finditer(s)
        for i in ret:
            yield {
                "id": i.group("id"),
                "title": i.group("title"),
                "rating_num": i.group("rating_num"),
                "comment_num": i.group("comment_num"),
            }
    
    
    def main(num):
        url = 'https://movie.douban.com/top250?start=%s&filter=' % num
        response_html = getPage(url)
        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 + "
    ")
    
    count = 0
    for i in range(10):
        main(count)
        count += 25
    复制代码
  • 相关阅读:
    Python爬虫入门教程 24-100 微医挂号网医生数据抓取
    Python爬虫入门教程 23-100 石家庄链家租房数据抓取
    Python爬虫入门教程 22-100 CSDN学院课程数据抓取
    Python爬虫入门教程 21-100 网易云课堂课程数据抓取
    MySQL MGR--MGR部署
    MySQL DDL--MySQL 5.7版本Online DDL操作
    MySQL Percona Toolkit--pt-osc与online DDL选择
    MySQL Percona Toolkit--pt-osc重点参数
    MySQL Percona Toolkit--pt-osc执行SQL命令
    MySQL Percona Toolkit--pt-osc学习
  • 原文地址:https://www.cnblogs.com/QQ279366/p/7834101.html
Copyright © 2011-2022 走看看