• Day 15 正则表达式 re模块


    1.正则表达式

      1.正则表达式不是Python独有的,它是一门独立的技术,如果在python中使用,必须导入re模块,正则表达式用来筛选字符串中的特定内容,一般情况下遇到reg都是与正则有关系

      2.如果匹配具体内容,可以直接西,不需要正则表达式

      3.正则表达式一般由元字符与量词组成

      4.元字符

    元字符 匹配内容与注意事项
    d digit   匹配所有数字         注[dD],[Ww],[sS] 任意一组可以匹配任意字符
    w word  匹配字母数字下划线
    s space  匹配所有空格(包括空格,制表符回车)
    D   匹配非数字的所有字符
    W   匹配所有非字母数字下划线的所有字符  
    S   匹配所有非空格的所有字符
      匹配回车符
      匹配制表符
       匹配一个单词的结尾
    .   匹配除换行符以外的所有字符
    ^   匹配字符串的开始                                       ^与$合用会精准的限制匹配内容,中间写什么就只匹配什么
    $   匹配字符串的结尾
    |   或  注:只会匹配或符号两边的其中一个,从左往右,  所以要把长的放在短的前面
    [..]   匹配字符组的字符 用[]来限定,一个字符组只针对一个字符,字符组里面的内容都是或的关系  可以[1-9] 但要注意里面数字必须是从小到大
    ()   匹配括号内的表达式,表示一个组
    [^...]   匹配非字符组里字符的内容   ^在字符组里是取反的意思

      5:量词. 必须跟在正则符号也就时元字符后面,并且量词只能限制它前面紧挨着他的表达式

    量词 使用说明
    *  匹配0次或无穷大次
    + 匹配1次或无穷大次
    ? 匹配0次或1次
    {n} 指定匹配重复n次
    {m,n} 指定匹配重复 m-n 次
    {m,} 指定匹配重复m次到无穷大次

      6.转义字符   当我们需要匹配的内容中就是需要匹配 而不是匹配换行符时就需要对 中的转义 如"\n"  "."(匹配.本身) 用转义

      7.贪婪匹配:  在满足匹配时,匹配尽可能长的字符串   

      8.惰性匹配:  在正则表达式量词后面加?  如 .*?    .+?  {m,n}?   {n,}?

      9.   .*? 的用法    .*?x   意思就是取前面任意长度的字符直到遇到X停止

    2.re模块: python中使用正则必须使用re模块

      1. re.findall  语法 re.findall('正则表达式', '待匹配的字符串')

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.findall('d',s)  # 找出字符串中正则表达式全部内容,返回一个列表,列表中元素就时正则匹配到的结果
    print(res)  # ['1', '4', '1', '4', '5', '3', '5']

      2. re.search  语法: re.search('正则表达式', '待匹配的字符串')

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.search('d',s)  # 只会依据正则查一次 只要查到了结果 就不会再往后查找
    print(res)  # 不会直接返回匹配到的结果,而返回一个对象   没匹配到返回None
    print(res.group())   # 1   必须用group 才能看到匹配到的结果  如果没匹配到会报错

      3. re.match    语法: re.match('正则表达式', '待匹配的字符串')

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.match('d',s)  # 只会匹配字符串开头部分
    print(res)  # 不会直接返回匹配到的结果,而返回一个对象   没匹配到返回None
    print(res.group())   # 1   必须用group 才能看到匹配到的结果  如果没匹配到会报错

      4. group   当使用re.search与re.match 时会返回一个对象.需要用group取值

      5. re.split  语法: re.split('正则表达式', '待匹配的字符串',切割次数)

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.split('d',s)  # 以匹配到的结果对字符串进行分割 返回一个列表
    print(res)  # ['', 'hkj', 'h', '', 'v', 'gh', '', 'mbjkkjk']

      6 .re.sub  语法: re.sub('正则表达式','新的内容' ,'待匹配的字符串',替换次数)

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.sub('d','哈哈',s)  # 将s中每一个能被匹配到的替换成哈哈  
    print(res)  # 哈哈hkj哈哈h哈哈哈哈v哈哈gh哈哈哈哈mbjkkjk

      7. re.subn 语法: re.subn('正则表达式','新的内容' ,'待匹配的字符串',替换次数)

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.subn('d','哈哈',s)  # 将s中每一个能被匹配到的替换成哈哈,返回一个元组,第二个元素是共替换的次数
    print(res)  # ('哈哈hkj哈哈h哈哈哈哈v哈哈gh哈哈哈哈mbjkkjk', 7) 

      8. re.compile  语法: re.compile('正则表达式')   将传入的正则表达式一次性编译,可以拿到任意地方运行.节省时间,提高开发效率

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.compile('[0-9]')  
    print(re.findall(res,s))  # ['1', '4', '1', '4', '5', '3', '5']

      9. re.finditer  语法: re.finditer('正则表达式', '待匹配的字符串')  返回一个存放匹配结果的迭代器  节省内存空间

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.compile('[0-9]')
    res1 = re.finditer(res,s)
    print(next(res1).group())   # 通过next得到一个对象,用group取值
    print(next(res1).group())
    print(next(res1).group())
    print(next(res1).group())
    print(next(res1).group())
    print(next(res1).group())
    print(next(res1).group())  # 当值取完继续去触发StopIteration异常

      10 re模块中分组的使用:

        (1)  按分组取

    import re
    res = re.search('^[1-9](d{14})(d{2}[0-9x])?$','130120122232422159')
    print(res.group())
    print(res.group(0))  # 与group 等价
    print(res.group(1))  # 第一个分组匹配到的内容
    print(res.group(2))  # 第二哥分组匹配到的内容

        (2) 起别名  在分组内使用 ?P<名字> 起别名,注意P大写,  注意用别名访问时别名需要加引号

    import re
    res = re.search('^[1-9](?P<name>d{14})(?P<pwd>d{2}[0-9x])?$','130120122232422159')
    print(res.group())
    print(res.group(0))  # 与group 等价
    print(res.group(1))  # 第一个分组匹配到的内容
    print(res.group(2))  # 第二哥分组匹配到的内容
    print(res.group('name'))  # name 匹配的内容
    print(res.group('pwd'))  # pwd 匹配的内容

        (3)  使用re.findall 分组存在时,分组优先      在分组内使用?:  取消优先

    import re
    ret1 = re.findall('www.(baidu|163).com', 'www.163.com')  # 分组优先
    print(ret1)   # ['163']
    ret2 = re.findall('www.(?:baidu|163).com', 'www.163.com')  # 分组内使用?:取消分组优先
    print(ret2)  # ['www.163.com']

        (4) 使用re.split 分组存在时不会将 匹配到内容丢掉

    import re
    s = '1hkj4h14v5gh35mbjkkjk'
    res = re.split('(d)',s) 
    print(res)  # ['', '1', 'hkj', '4', 'h', '1', '', '4', 'v', '5', 'gh', '3', '', '5', 'mbjkkjk']

    3 爬虫案例.

    import requests
    
    import re
    import json
    
    
    def getPage(url):
        response = requests.get(url)
        return response.text
    
    
    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)
    
        f = open("move_info7", "a", encoding="utf8")
    
        for obj in ret:
            print(obj)
            data = json.dumps(obj, ensure_ascii=False)
            f.write(data + "
    ")
    
    
    if __name__ == '__main__':
        count = 0
        for i in range(10):
            main(count)
            count += 25
  • 相关阅读:
    2017.3.13-afternoon
    2017.3.13-morning
    2017.3.10-afternoon
    2017.3.10-morning
    2017.3.9-afternoon
    2017.3.9-morning
    神经网络入门
    webpack 安装
    git 常用命令
    mysql 用户管理和权限设置
  • 原文地址:https://www.cnblogs.com/yanglingyao/p/11201991.html
Copyright © 2020-2023  润新知