• 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"))
  • 相关阅读:
    NET中的幕后英雄:MSCOREE.DLL (转载)
    【百度地图API】如何使用suggestion下拉列表方式的搜索建议
    经典收藏 50个jQuery Mobile开发技巧集萃
    深入理解Android消息处理系统——Looper、Handler、Thread
    Android GridView宫格视图(一) 运用BaseAdapter
    Toast和Handler的间隔使用
    android Toast大全(五种情形)建立属于你自己的Toast
    SQL 新特性 output
    通过Aspose.Cells.dll组件,实现多sheet导出Xls
    SQL 通过镜像数据库实现 故障自动切换
  • 原文地址:https://www.cnblogs.com/root0/p/10330859.html
Copyright © 2020-2023  润新知