• Python开发【第五篇】: 内置模块


    内容概要

    1. 二分查找、冒泡
    2. random
    3. time
    4. os
    5. sys
    6. pickle
    7. json
    8. shelve
    9. re

    1、二分查找和冒泡排序

     01. 二分查找

     二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

      优点: 快

      缺点: 必须是有序序列

     核心思想:

    掐头结尾找中间,出口:左边比右边大
    目标数与中间数去比较,比中间数小则砍掉左边的一半,再去和剩下的中间数比较。以此类推。
    # 非递归算法
    lst = [1,4,6,8,9,12,15,22,33,45,56,78,89]
    n = int(input("n:"))
    
    left = 0    #开头
    right = len(lst) -1   #结尾
    while left <= right:
        mid = (left + right) // 2  # 中间
        if n > lst[mid]:   # 目标数比中间大
            left = mid + 1  # 左边索引变为中间索引 +1
        elif n < lst[mid]:  # 目标数比中间小
            right = mid - 1  # 右边索引变为中间索引 -1
        else:
            print("找到了")
            break
    else:
        print("没有找到该数据")

     02. 冒泡排序

    #  python 数据互换

    a = 10
    b = 20
    print(a,b)
    #10 20
    a,b = b,a
    print(a,b)
    #20 10

      它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素已经排序完成。

    lst = [1, 12, 2, 38, 4,  56, 1, 2,   31]
    
    # 列表里面的 lst[i] 与 lst[i+1]做比较
    for el in lst:  # 控制循环次数
        for i in range(len(lst)-1): # 列表索引,比较到最后索引的前一位
            if lst[i] > lst[i+1]:  # 前面的比后面的大,就进行交换
                lst[i],lst[i+1] = lst[i+1],lst[i]
    print(lst)

    2、random 随机数

    import random
    #随机数函数
    print(random.random()) # 0-1随机小数
    
    print(random.uniform(10,20)) # 10-20之间的随机小数
    
    #随机整数
    print(random.randint(10,20)) #10-20之间的整数
    
    # 36选7 不能重复(使用集合)
    s = set()
    while len(s) < 7:
        s.add(random.randint(1,36))
    print(s)
    
    lst = ["飞驰人生", "情圣2", "疯狂外星人", "啥是佩奇"]
    
    print(random.choice(lst))  # 随机出来一个
    
    print(random.sample(lst,2)) # 随机出来n个
    
    random.shuffle(lst)  #随机打乱列表
    print(lst)

    随机生成字母

    import random
    import string
     
    s = string.ascii_lowercase #所有小写字母(a-z)
    #s=string.ascii_letters #所有大小写字母(a-z,A-Z)
    #s=string.ascii_uppercase #所有大写字母(A-Z)
    r = random.choice(s)

    2、time 时间模块

     在python中时间分成三种表现形式: 

    时间戳(timestamp). 时间戳使用的是从1970年01月01日 00点00分00秒到现在一共经过了多少秒... 使用float来表示。 中国在东八区。

    # 获取当前系统时间、给机器的看的
    print(time.time())   
    # 时间戳  1548666510.6973913

    格式化时间(strftime). 这个时间可以根据我们的需要对时间进行任意的格式化.

    # 格式化时间,给人的看的。字符串
    print(time.strftime("%Y-%m-%d %H:%M:%S"))  # 2019-01-28 17:08:30 常用格式
    日期格式化的标准:
    %y 两位数的年份表示(00-99%Y 四位数的年份表示(000-9999%m 月份(01-12%d 月内中的一天(0-31%H 24小时制小时数(0-23%I 12小时制⼩时数(01-12%M 分钟数(00=59%S 秒(00-59%a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 一年内的一天(001-366%p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W ⼀年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %z 当前时区的名称 %% %号本身

    结构化时间(struct_time). 这个时间主要可以把时间进行分类划分. 比如. 1970年01月01日 00点00分00秒 这个时间可以被细分为年, 月, 日.....一大堆东西.

    # 结构化时间 -> python程序中的时间
    print(time.localtime())
    #time.struct_time(tm_year=2019, tm_mon=1, tm_mday=28, tm_hour=17, tm_min=8, tm_sec=30, tm_wday=0, tm_yday=28, tm_isdst=0)
    时间格式之间的转化:
    # 把数字转化成格式化时间
    n = 18888888
    # 1. 把时间戳转化成结构化时间
    # struct_time = time.localtime(n)
    
    # 2. 把结构化时间转化成格式化时间
    # s = time.strftime("%Y-%m-%d %H:%M:%S",struct_time)
    # print(s)
    
    # 时间戳 -->  结构化时间  --> 格式化时间
    # 把格化式时间转化为时间戳。
    s = "1970-08-07"
    # 1. 把格式化时间转化成结构化时间
    struct_time = time.strptime(s,"%Y-%m-%d") # 参数1:时间字符串 参数2:格式
    
    # 2. 把结构化时间转化成时间戳
    n = time.mktime(struct_time)
    print(n)
    
    # 格式化时间 -> 结构化时间 -> 时间戳
    时间差的计算:
    # # 时间差的计算 -> 针对小时来计算
    #1. 获取开始和结束时间
    s1 = input("开始时间(格式:yyyy-mm-dd HH:MM:SS):")
    s2 = input("结束时间(格式:yyyy-mm-dd HH:MM:SS):")
    
    # #2. 把这两个时间都转化为时间戳
    n1 = time.mktime(time.strptime(s1,"%Y-%m-%d %H:%M:%S"))
    n2 = time.mktime(time.strptime(s2,"%Y-%m-%d %H:%M:%S"))
    
    # 3. 计算时间差
    diff_n = abs(n2 - n1)   #结果是秒级别的时间差
    
    #把秒转化为分钟
    ret_min = diff_n // 60
    ret_sec = diff_n % 60 
    
    # 把分钟转化为小时
    ret_hour = ret_min // 60
    ret_hour_min = ret_min % 60  # 计算余数,一小时多少分钟
    print("过去了 %s 小时 %s 分钟 %s 秒" %(ret_hour,ret_hour_min,ret_sec))

    3、sys模块

    所有和python解释器相关的都在sys模块. 

    sys.argv         获取命令行参数List,第0个元素是程序本身路径
    sys.exit(n)      退出程序,正常退出时exit(0),错误退出sys.exit(1)
    sys.version      获取Python解释程序的版本信息
    sys.path         返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    sys.platform     返回操作系统平台名称

    4、os模块

    所有和操作系统相关的内容都在os模块

    目录操作
    os.makedirs("a/b/c")  # 创建多层递归目录  相当于shell中mkdir dirname -p
    os.removedirs("a/b/c")  # (只删除空目录)若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    
    os.mkdir("a/b")    #创建单级目录;相当于shell中mkdir dirname
    os.rmdir("a/b")    #删除单级空目录,若目录不为空则无法删除,报错;只删除b目录
    
    print(os.listdir('d://'))   # 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表形式打印

    文件操作
    os.remove()     # 删除一个文件
    os.remove("oldname","newname")  # 重命名文件/目录
    
    os.stat('path/filename')    # 获取文件/目录属性信息
    stat 结构:
    st_mode: inode 保护模式
    st_ino: inode 节点号。
    st_dev: inode 驻留的设备。
    st_nlink: inode 的链接数。
    st_uid: 所有者的用户ID。
    st_gid: 所有者的组ID。
    st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据。
    st_atime: 上次访问的时间。
    st_mtime: 最后一次修改的时间。
    st_ctime: 由操作系统报告的"ctime"。在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如Windows)是创建时间。

    执行shell命令
    os.system("bash command")  # 运行 shell命令,直接显示
    os.popen("bash command").read()  #运行shell命令,获取执行结果
    print(os.getcwd())    #获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")   #改变当前脚本工作目录;相当于shell下cd
    os.path
    print(os.path.abspath("a"))  # 返回一个相对路径的绝对路径
    
    将path分割成目录和文件件名,返回元祖。
    print(os.path.split("E:python-25期课上代码day05课上代码今日内容大纲"))
    ('E:\python-25期课上代码\day05\课上代码', '今日内容大纲')
    
    # 拿到文件或者文件夹的上级目录
    print(os.path.dirname("E:python-25期课上代码day05课上代码今日内容大纲"))
    执行结果:
    E:python
    -25期课上代码day05课上代码 # 拿到文件或者文件夹的名字 print(os.path.basename("E:python-25期课上代码day05课上代码今日内容大纲")) 执行结果:
    今日内容大纲 一些判断 print(os.path.exists(
    "a")) #如果path存在,返回True;如果path不存在,返回False print(os.path.isabs("a")) #如果path是绝对路径,返回True print(os.path.isfile("今日内容大纲")) #如果path是一个存在的文件,返回True。否则返回False print(os.path.isdir("E:python-25期课上代码day05")) #如果path是一个存在的目录,则返回True。否则返回False 文件路径的拼接 print(os.path.join("E:python-25期课上代码day05","课上代码"))
    执行结果:
    E:python
    -25期课上代码day05课上代码

    查看目录或文件属性
    os.path.getatime(path)       #返回path所指向的文件或者目录的最后访问时间
    os.path.getmtime(path)       #返回path所指向的文件或者目录的最后修改时间
    os.path.getsize(path)        #返回path的大小

    特殊属性:
    print(os.sep)     #输出操作系统特定的路径分隔符,   win下为"\",Linux下为"/"
    print(os.linesep)  #输出当前平台使用的行终止符,    win下为"
    ",Linux下为"
    "
    print(os.pathsep)  #输出用于分割文件路径的字符串    win下为;,Linux下为:
    print(os.name)     #输出字符串指示当前使用平台。    win->'nt';  Linux->'posix'
    文件复制 -> 写函数. 给两个参数. 两个文件路径. 把文件从a复制到b
    def file_copy(src_file,dest_file):
        dest_dir = os.path.dirname(dest_file)  # 获取目标文件的上层目录
        if not os.path.exists(src_file):  # 判断源文件是否存在
            print(" %s 文件路径找不到" % src_file)
            return False
        elif not os.path.isdir(dest_dir): # 判断目录是否存在
            os.makedirs(dest_dir)  # 不存在则创建
        with open(src_file,mode="rb") as f1, 
            open(dest_file,mode="wb") as f2:
            for content in f1:
                f2.write(content)
    
    file_copy("D:胡一菲.jpg",r"F:	ac.jpg")
    
    

    4、序列化模块

    一、什么是序列化?

        在存储数据或者网络传输数据的时候. 需要对我们的对象进行处理. 把对象处理成方便存储和传输的数据格式. 这个过程叫序列化. 不同的序列化, 结果也不同. 但是目的是一样的. 都是为了存储和传输.
    在python中存在三种序列化的方案:
      1. pickle. 可以将我们python中的任意数据类型转化成bytes并写入到文件中. 同样也可以把文件中写好的bytes转换回我们python的数据. 这个过程被称为反序列化
      2. shelve. 简单另类的一种序列化的方案. 有点类似redis持久化. 可以作为一种小型的数据库来使用
      3. json. 将python中常用的字典, 列表转化成字符串. 是目前前后端数据交互使用频率最高的一种数据格式.

     

    二. pickle(重点)
     pickle用起来很简单. 说白了. 就是把python对象写入到文件中的一种解决方案.但是写入到文件的是bytes. 所以这东西不是给人看的. 是给机器看的.

    # 序列化  将对象序列化为字节
    lst = ["大象", "胡辣汤", "馒头", "汪峰"]
    bs = pickle.dumps(lst)
    print(type(bs))  # bytes类型的
    print(bs)
    
    # 反序列化 将字节反序列化为我们的对象
    ll = pickle.loads(bs)
    print(ll)

    把序列化的对象写入到文件中
    lst = ["越狱","大圣归来","啥是佩琪","疯狂外星人"]
    
    pickle.dump(lst,open("pik.dat",mode="ab"))
    f = open("pik.dat",mode="rb")
    
    while 1:
        try:
            obj = pickle.load(f)
            print(obj)  #数据读完会报错,EOFError: Ran out of input
        except EOFError:
            print("没数据了")
            break
    
     但是这样写并不够好. 因为读的时候. 并不能知道有多少对象要读. 不能一行一行的读.

    那真的要写入或者读取多个内容怎么办? 很简单. 装list里. 然后读取和写入都用list
    d1 = {"name":"游艇", "price":"18888"}
    d2 = {"name":"手机", "singer":"5600"}
    d3 = {"name":"电脑", "singer":"9800"}
    d4 = {"name":"鼠标", "singer":"260"}
    
    # 把这些数据写入到一个列表中,然后统一把列表写入到文件中
    lst = [d1,d2,d3,d4]
    pickle.dump(lst,open("pik.dat",mode="wb"))
    
    # 读取,这样写比较安全,但是效率相对较低.
    lst = pickle.load(open("pik.dat",mode="rb"))
    for el in lst:
        print(el)

    序列化
      dumps
      dump -> 写入文件

    反序列化
      loads
      load -> 读取文件

    pickle序列化的内容是二进制的内容(bytes) 不是给人看的.

    三. json(重点)

       json是我们前后端交互的枢纽. 相当于编程界的普通话. 大家沟通都用json. 为什么这样呢? 因为json的语法格式可以完美的表示出一个对象. 那什么是json: json全称javascript object notation. 翻译过来叫js对象简谱. 很复杂是吧? 来上一段我们认识的代码:

    d = {
        "name":"汪峰",
        "wife":{
            "name":"章子怡",
            "外号":"国际章",
            "hello":None,
            "喜欢你":False,
            "喜欢我":True
        },
        "children":[
            {"name":"孩1"},
            {"name":"孩2"}
        ]
    }

      

      这个不是字典么? 对的. 在python里这玩意叫字典. 但是在javascript里这东西叫json. 一模一样的. 我们发现用这样的数据结构可以完美的表示出任何对象. 并且可以完整的把对象表示出来. 只要代码格式比较好. 那可读性也是很强的. 所以大家公认用这样一种数据结构作为数据交互的格式. 那在这个鬼东西之前是什么呢? XML.....来看一段代码

    <?xml version="1.0" encoding="utf-8" ?>
    <wf>
        <name>汪峰</name>
        <age>18</age>
        <hobby>上头条</hobby>
        <wife>
            <name>⼦怡</name>
            <age>18</age>
            <hobbies>
                <hobby>唱歌</hobby>
                <hobby>跳舞</hobby>
                <hobby>演戏</hobby>
                </hobbies>
        </wife>
     
    </wf>

      之前都是用这样的数据进行传输的. xml在维护和处理上是非常复杂和繁琐的.

    
    

    我们的程序是在python里写的. 但是前端是在JS那边来解析json的. 所以. 我们需要把我们程序产生的字典转化成json格式的json串(字符串). 然后网络传输. 那边接收到了之后. 它爱怎么处理是它的事情.

    # 把python字典转化为json格式

    import json
    d = {
        "name":"汪峰",
        "wife":{
            "name":"章子怡",
            "外号":"国际章",
            "hello":None,
            "喜欢你":False,
            "喜欢我":True
        },
        "children":[
            {"name":"孩1"},
            {"name":"孩2"}
        ]
    }
     print(d)
    
    s
    = json.dumps(d,ensure_ascii=False) # 默认情况下中文是不显示的. ensure_ascii=False 处理中文 print(s)

    把json格式转化为字典
    ss = '{"name": "汪峰", "wife": {"name": "章子怡", "外号": "国际章", "hello": null, "喜欢你": false, "喜欢我": true}, "children": [{"name": "孩1"}, {"name": "孩2"}]}'
    print(type(ss))
    obj = json.loads(ss)
    print(obj)

      # json也可以像pickle一样把序列化的结果写入到文件中.

     json.dump 第一个参数是 对象,第二参数是 文件

    dic = {"a":"女王","b":"萝莉","c":"小清新"}
    f = open("test.json",mode="w",encoding="utf-8")
    json.dump(dic,f,ensure_ascii=False)
    f.close()

       也可以写到一行

    lst = ["周杰伦",None,False,123]
    json.dump(lst,open("jay.json",mode="w",encoding="utf-8"),ensure_ascii=False)

    # 从文件中读取json
    f = open("test.json",mode="r",encoding="utf-8")
    dic = json.load(f)
    f.close()
    print(dic)
    也可以写到一行
    print(json.load(open("jay,json",mode="r",encoding="utf-8")))
    # 可以向同一个文件写入多个json串,但是读不行。
    lst = [{"a":1},{"b":2}]
    f = open("test.json",mode="w",encoding="utf-8")
    for el in lst:
        json.dump(el,f)
    f.close()
    #  此时文件中的内容是一行内容
    # {"a": 1}{"b": 2}

      这在读取的时候是无法正常读取的. 那如何解决呢? 两套方案. 方案一. 把所有的内容准备好统一进行写入和读取. 但这样处理, 如果数据量小还好. 数据量大的话, 就不够友好了. 方案二. 不用dump. 改用dumps和loads. 对每一行分别进行处理.

       #  即使用 for 循环遍历,一行一行的写,一行一行的读

    lst = [{"a":1},{"b":2},{"c":3},{"d":"李世超"}]
    
    # 写入
    f = open("test.json",mode="w",encoding="utf-8")
    for el in lst:
        s = json.dumps(el,ensure_ascii=True) + "
    "
        f.write(s)
    f.close()
    
    # 读取
    f = open("test.json",mode="r",encoding="utf-8")
    for line in f:
        dic = json.loads(line)
        print(dic)
    f.close()



    四. shalve模块
      shelve提供python的持久化操作. 什么叫持久化操作呢? 就是把数据写到硬盘上.在操作shelve的时候非常的像操作一个字典。
    import shelve
    shelf = shelve.open("dump.rdb")  # 打开一个文件
    
    # 操作shelf 就像操作字典一样
    # 添加
    shelf["jay"] = "周杰伦"
    
    # 查询
    print(shelf["jay"])
    shelf.close()

    这个东西和字典差不多. 只不过你的字典是一个文件. 接下来, 我们存储一些复杂的数据

    # 存一些复杂的数据
    s = shelve.open("dump.rdb")
    s["jay"] = {"name":"周杰伦","age":18,"hobby":"哄小孩"}
    print(s["jay"])
    s.close()
    
    # 但是有坑
    s = shelve.open("dump.rdb")
    s["jay"]["name"] = "李世超"  # 修改字典中的数据
    s.close()
    
    s = shelve.open("dump.rdb")
    print(s["jay"]["name"])  # 并没有改变
    s.close()
    # 解决方案
    s = shelve.open("dump.rdb",writeback=True)
    s["jay"]["name"] = "李世超"   # 修改字典中的数据
    s.close()
    
    s = shelve.open("dump.rdb")
    print(s["jay"])     # 改变了
    s.close()

    writeback = True 可以动态的把我们修改的信息写入到文件中. 还可以删除数据. 就像字典一样.
    s = shelve.open("dump.rdb",writeback=True)
    del s["jay"]
    s.close()
    
    s = shelve.open("dump.rdb")
    print(s["jay"])   # 报错了,key 被删除了
    s.close()
    
    s = shelve.open("dump.rdb",writeback=True)
    s["jay"] = "周杰伦"
    s["wjl"] = "王力宏"
    s.close()
    
    # 像字典一样操作
    s = shelve.open("dump.rdb")
    for k in s:
        print(k)
    
    for k,v in s.items():
        print(k,v)



    5、正则表达式

    正则表达式是对字符串操作的一种逻辑公式. 我们一般使用正则表达式对字符串进行匹配和过滤. 使用正则的优缺点:
      优点: 灵活, 功能性强, 逻辑性强.
      缺点: 上手难. 一旦上手, 会爱上这个东西


    工具: 各大文本编辑器一般都有正则匹配功能. 我们也可以去 http://tool.chinaz.com/regex/ 进行在线测试.

    正则表达式由普通字符和元字符组成. 普通字符包含大小写字母, 数字. 在匹配普通字符的时候我们直接写就可以了. 比如"abc" 匹配的就是"abc". 我们如果用python也可以实现相同的效果. 所以普通字符没什么好说的. 重点在元字符上.

    元字符: 元字符才是正则表达式的灵魂. 元字符中的内容太多了, 先看一些常用的。

    1. 字符组
      字符组很简单用 [] 括起来. 在 [] 中出现的内容会被匹配. 例如:[abc] 匹配a或b或c
      如果字符组中的内容过多还可以使用- , 例如: [a-z] 匹配a到z之间的所有字母 [0-9]匹配所有阿拉伯数字
      [a-zA-Z0-9] 匹配所有大小写字母和数字

     


    2. 简单元字符
      .        匹配除换行符以外的任意字符
      w     匹配字母或数字或下划线
      s      匹配任意的空白符(空格、换行、制表符)
      d        匹配数字(0-9)
      W    匹配非字母或数字或下划线 (!@#$%^%&^*)这些
      D     匹配非数字
      S     匹配非空白符 (与小写相反)

           匹配一个换行符
             匹配一个制表符
           匹配一个单词的结尾
      ^      匹配字符串的开始
      $      匹配字符串的结尾
      a|b      匹配字符a或字符b
      ()      匹配括号内的表达式,也表示一个组
      [...]   匹配字符组中的字符
      [^...]    匹配除了字符组中字符的所有字符,取反


    3. 量词
      我们到目前匹配的所有内容都是单一文字符号. 那如何一次性匹配很多个字符呢,我们要用到量词
      *        重复零次或更多次
      +       重复一次或更多次
      ?       重复零次或一次
      {n}     重复n次
      {n,}    重复n次或更多次
      {n,m}    重复n到m次

     

     

    4. 惰性匹配和贪婪匹配

      在量词中的 *,  + , {}  都属于贪婪匹配。 就是尽可能多的匹配到结果。

    str = "麻花藤昨天让英雄联盟关服了"
    print(re.findall(r"麻花藤.*",str))
    # 执行结果:
    # ['麻花藤昨天让英雄联盟关服了']


    在使用.*后面如果加了? 则是尽可能的少匹配。 表示惰性匹配

    str = "麻花藤昨天让英雄联盟关服了"
    print(re.findall(r"麻花藤.*?",str))
    # 执行结果:
    # ['麻花藤']
    <.*?> 的特殊含义 找到下一个 > 为止。
    str = "<div>胡辣汤<div>"
    print(re.findall(r"<.*>",str))
    # 执行结果:
    # ['<div>胡辣汤<\div>']
    
    print(re.findall(r"<.*?>",str))
    # 执行结果:
    # ['<div>', '<\div>']

    5. 转义

     # 在正则中使用 来对有特殊意义的字符转义

    print(re.findall(r"
    ","你好啊
    "))   # 匹配 
    
    print(re.findall(r"[]","你好啊[]"))  # 匹配[],[]在正则中有特殊意义 要转义
    # 执行结果:
    # ['
    ']
    # ['[]']

     

    6、re模块

        re模块是python提供的一套关于处理正则表达式的模块. 核心功能有四个: 

    1. findall 可以通过正则匹配到字符串中的内容,返回列表,匹配不到结果返回空列表
    第一个参数正则表达式的规则
    第二个参数字符串
    obj = re.findall(r"d+","我在30岁,一定要赚够100w")  # 匹配数字
    print(obj)
    #执行结果: ['30', '100']

    2. search 如果没有匹配到结果,返回None

    如果匹配到了第一个结果就返回
    ret = re.search(r"d+d+", "我在30岁,一定要赚够100w").group()
    print(ret)
    执行结果: <_sre.SRE_Match object; span=(2, 4), match='30'>
    
    print(ret.group()) # 必须分组拿数据 执行结果:
    30 # 只能匹配到30
    # f = open('ip.all-update','r').readlines()
    # for line in f:
    #     if not line == "
    ": # 排除文件中的空行
    #         s = line.strip()
    #         ip = re.search(r"(d+.d+.d+.d+)(s)(.*)",s).group(1)  # group(1) 表示前面的括号1匹配到的内容
    #         print(ip)

    3. match
    obj = re.mat# 3. matchch(r"d+","我在30岁,一定要赚够100w")
    print(obj)
    执行结果: None
    
    # match 会从字符串的开头进行匹配,匹配到结果就返回
    obj = re.match(r"d+","10 我在30岁,一定要赚够100w")
    print(obj.group())
    #执行结果: 10

    4. finditer 和 findall 一样,返回的是迭代器
    it = re.finditer(r"d+","10 我在30岁,一定要赚够100w")
    print(it)
    #执行结果: <callable_iterator object at 0x00000000021CF400>
    for el in it: print(el.group()) # 依然需要分组 # 执行结果: # 10 # 30 # 100
    5. 其他操作
     01. re中的分组,小括号:()
    # 匹配 "哈哈哈哈"四个字
    # 不加括号
    print(re.findall(r"<div>哈{4}</div>","<div>哈哈哈哈</div>"))
    # 执行结果: ['<div>哈哈哈哈</div>']
    
    # 加上括号
    print(re.findall(r"<div>(哈{4})</div>","<div>哈哈哈哈</div>"))
    # 执行结果: ['哈哈哈哈']
    
    取值的优先级,想要的数据括起来
    it = re.finditer(r"<div>电影名: (.*?)下载链接: (.*?)</div>","<div>电影名: 羞羞的铁拳 下载链接: http://www.baidu.com</div>")
    for i in it:
        print(i.group(1))  # 取第一个小括号匹配到的内容
        print(i.group(2))  # 第二个小括号匹配到的内容
    
    # 执行结果: 羞羞的铁拳 http:
    //www.baidu.com
    # 给分组取名字 -> ?P<名字>
    it = re.finditer(r"<div>电影名: (?P<name>.*?)下载链接: (?P<url>.*?)</div>","<div>电影名: 羞羞的铁拳 下载链接: http://www.baidu.com</div>")
    for el in it:
        print("电影名:",el.group("name"))   # 根据分组名字取数据
        print("下载链接:",el.group("url"))
    
    # 执行结果: # 电影名: 羞羞的铁拳 # 下载链接: http:
    //www.baidu.com

    02.
    compile 预加载正则.
    obj = re.compile(r"d+")  # 先写好正则,后面直接用
    print(obj.findall("10 我在30岁,一定要赚够100w"))
    
    #执行结果: [
    '10', '30', '100']

    03. split 切割
    lst = re.split(r"d+","我今年25,要在30岁赚够100W")
    print(lst)
    # 执行结果:  按照数字切割
    # ['我今年', ',要在', '岁赚够', 'W']
    
    # 加上小括号
    lst = re.split(r"(d+)","我今年25,要在30岁赚够100W")
    print(lst)
    # 执行结果: 保留了匹配的项
    # ['我今年', '25', ',要在', '30', '岁赚够', '100', 'W']
    
    ret = re.split('[ab]', 'qberafjbcd') # 先按'a'分割得到'qber''fjbcd',在对'qber''fjbcd'分别按'b'分割
    print(ret)
    # 执行结果:
    # ['q', 'er', 'fj', 'cd']

    04. sub 替换,把字符串中的数字换成 _HHH_
    ret = re.sub("d+","_HHH_","alix123taibai45xiongmao78")
    print(ret)
    # 执行结果: 匹配到的数字全部换成了 _HHH_
    # alix_HHH_taibai_HHH_xiongmao_HHH_

    subn 显示替换的次数
    ret = re.subn("d+","_HHH_","alix123taibai45xiongmao78")
    print(ret)
    # 执行结果: 显示了更换的次数
    # ('alix_HHH_taibai_HHH_xiongmao_HHH_', 3)

    re练习,爬取电影天堂

    #!/usr/bin/env python3
    # _*_ coding:utf-8 _*_
    from urllib.request import urlopen
    import re
    
    # 1. 获取网页内容
    url = "https://www.dytt8.net/html/gndy/dyzz/20190213/58205.html"
    content = urlopen(url).read().decode("gbk")
    # print(content)
    
    # 2. 写正则,匹配电影名字和下载链接
    obj = re.compile(r'<div id="Zoom">.*?◎译  名 (?P<name>.*?) <br />.*?<td.*?<a href="(?P<url>.*?)">ftp',re.S)  # re.S 让 . 可以匹配换行
    
    # 3. 匹配网页内容
    ret = obj.finditer(content)
    for el in ret:
        print("电影名:",el.group("name"))
        print("下载链接:",el.group("url"))
  • 相关阅读:
    Educational Codeforces Round 86 (Rated for Div. 2) D. Multiple Testcases
    Educational Codeforces Round 86 (Rated for Div. 2) C. Yet Another Counting Problem
    HDU
    HDU
    HDU
    HDU
    Good Bye 2019 C. Make Good (异或的使用)
    Educational Codeforces Round 78 (Rated for Div. 2) C. Berry Jam
    codeforces 909C. Python Indentation
    codeforces1054 C. Candies Distribution
  • 原文地址:https://www.cnblogs.com/root0/p/10330859.html
Copyright © 2020-2023  润新知