• day14~16 (常用模块)


    # 时间模块优先掌握的操作
    
    # 一:time
    
    # 时间分为三种格式:
    # 1、时间戳(timestape):从1970年到现在经过的秒数
    #    作用:用于时间间隔的计算
    
    # print(time.time())
    
    # 2、格式化的时间字符串(format string): 按照某种格式显示的时间:2020-03-30 11:11:11
    #    作用:用于展示时间
    
    # time.strftime('%Y-%m-%d %H:%M:%S %p')
    # time.strftime('%Y-%m-%d %X')
    
    # 3、结构化的时间(struct_time)
    #    作用:用于单独获取时间的某一部分
    
    # res=time.localtime()  # 本地时区的struct_time
    # tm_year=, tm_mon=, tm_mday=, tm_hou=, tm_min=, tm_sec=, tm_wday(一年中第几周)=, tm_yday(一年中第几天)=, tm_isdst(夏令时)=
    # print(res.tm_yday)
    
    # time.gmtime   # UTC时区的struct_time
    
    # 二:datetime
    import datetime
    
    # print(datetime.datetime.now())  -> 2020-03-30 14:52:31.833672
    # 作用:用来进行时间运算
    
    # print(datetime.datetime.now() + datetime.timedelta(days=3))   #datetime.timedelta 用来盛放需要增加或减少的时间
    # print(datetime.datetime.now() + datetime.timedelta(weeks=1))
    
    
    # 时间模块需要掌握的操作
    
    # 1、时间格式的转换
    
    # struct_time->时间戳
    import time
    
    # s_time=time.localtime()
    # print(time.mktime(s_time))
    
    # 时间戳->struct_time
    # tp_time=time.time()
    # print(time.localtime(tp_time))
    # print(time.gmtime(333333333))
    
    # struct_time->格式化的字符串形式的时间
    # s_time=time.localtime()
    # print(time.strftime('%Y-%m-%d %H:%M:%S',s_time))
    
    # 格式化字符形式的时间->struct time
    # print(time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S'))
    
    
    # format string<------>timestamp  (重点掌握)
    # '1988-03-03 11:11:11'+7
    
    # format string--->struct_time--->timestamp
    # struct_time=time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S')
    # timestamp=time.mktime(struct_time)+7*86400
    # print(timestamp)
    
    # format string<---struct_time<---timestamp
    # res=time.strftime('%Y-%m-%d %X',time.localtime(timestamp))
    # print(res)
    
    # time.sleep(3)
    
    # 了解知识
    # import time
    # print(time.asctime())  把一个表示时间的元祖或struct_time表示为:sun jun 20 23:21:05 1993 这种形式
    
    # import datetime
    # print(datetime.datetime.now())
    # print(datetime.datetime.utcnow()) # 世界标准时间
    
    print(datetime.datetime.fromtimestamp(333333)) # 时间戳直接转换为格式字符形式的日期
    
    # import random  随机取数
    # print(random.random()) #(0,1)----float    大于0且小于1之间的小数
    # print(random.randint(1, 3))  # [1,3]    大于等于1且小于等于3之间的整数
    # print(random.randrange(1, 3))  # [1,3)    大于等于1且小于3之间的整数
    # print(random.choice([111, 'aaa', [4, 5]]))  # 1或者23或者[4,5]
    # print(random.sample([111, 'aaa', 'ccc','ddd'],2))  # 列表元素任意2个组合
    # print(random.uniform(1, 3))  # 大于1小于3的小数,如1.927109612082716
    # item = [1, 3, 5, 7, 9]
    # random.shuffle(item)  # 打乱item的顺序,相当于"洗牌"
    # print(item)
    
    # 应用:随机验证码
    
    # import random
    #
    # res=''
    # for i in range(6):
    #     从26大写字母中随机取出一个=chr(random.randint(65,90))  chr[65]~chr[90] 参考的ASCII码表,对应A~Z
    #     从10个数字中随机取出一个=str(random.randint(0,9))
    #
    #     随机字符=random.choice([从26大写字母中随机取出一个,从10个数字中随机取出一个])
    #     res+=随机字符
    
    
    import random
    
    
    def make_code(size=4):
        res = ''
        for i in range(size):
            s1 = chr(random.randint(65, 90))
            s2 = str(random.randint(0, 9))
            res += random.choice([s1, s2])
        return res
    
    
    print(make_code(6))
    
    # import os
    
    # 获取某一个文件夹下所有的子文件以及子文件夹的名字
    # res=os.listdir('.')
    # print(res)
    
    # 返回path的大小
    # size=os.path.getsize(r'/Users/linhaifeng/PycharmProjects/s14/day22/01 时间模块.py')
    # print(size)
    
    # os.remove()  删除一个文件
    # os.rename("oldname","newname")  重命名文件/目录
    
    
    # 运行系统命令:应用程序向操作系统发送系统调用运行相关命令
    # os.system("dir r'C:\a'")
    
    # 得到一个字典,规定:key与value必须都为字符串
    # os.environ['aaaaaaaaaa']='111'  获取系统环境变量,范围更广
    # print(os.environ)
    
    
    # print(os.path.dirname(r'/a/b/c/d.txt'))
    # print(os.path.basename(r'/a/b/c/d.txt')) 返回path最后的文件名
    
    
    # print(os.path.isfile(r'笔记.txt')) 当前文件夹下是否存在文件
    # print(os.path.isdir(r'aaa'))  当前文件夹下是否存在文件夹
    
    # print(os.path.join('a','/','b','c','d')) path拼接
    
    
    # 三种获得上上一层文件夹路径的方法
    # BASE_DIR=os.path.dirname(os.path.dirname(__file__)) 推荐这种
    # print(BASE_DIR)
    
    # normpath 规范化路径
    # BASE_DIR=os.path.normpath(os.path.join(__file__,#     '..',#     '..'# ))
    
    
    # 在python3.5之后,推出了一个新的模块pathlib
    # from pathlib import Path
    # res = Path(__file__).parent.parent
    # print(res)
    
    
    # res=Path('/a/b/c') / 'd/e.txt'
    # print(res)
    
    # print(res.resolve())
    
    
    # import sys
    
    # python3.8 run.py 1 2 3
    # sys.argv 命令行参数别表,第一个元素是路径本身,用来接收外面传进来的值,也就是获取解释器后的参数值
    # print(sys.argv)
    
    # 【案例  文件copy脚本】
    
    # import os
    # src_file=sys.argv[1]
    # dst_file=sys.argv[2]
    # def copy_file():
    #   if not os.path.isfile(src_file):
    #       print('请输入正确的源文件路径')
    #       rutern
    #   if not os.path.isfile(dst_file):
    #       print('请输入正确的目标文件路径')
    #      return
    #   with open(r'%s' %src_file,mode='rb') as read_f,
    #       open(r'%s' %dst_file,mode='wb') as write_f:
    #       for line in read_f:
    #           write_f.write(line)
    
    # python3.8 run.py src_file dst_file
    
    #
    # 【案例:模拟下载及打印进度条】
    
    import time
    
    
    def progress(percent):
        if percent > 1:
            percent = 1
        res = int(50 * percent) * '#'
        print('
    [%-50s] %d%%' % (res, int(100 * percent)), end='')
    
    
    recv_size = 0
    total_size = 1025011
    
    while recv_size < total_size:
        time.sleep(0.01)
        recv_size += 1024
    
        # 打印进度条
        percent = recv_size / total_size  # 1024 / 333333
        progress(percent)
    
    # # shutil(了解)
    # import shutil
    #
    # shutil.copyfileobj(open('old.xml', 'r'), open('new.xml', 'w'))
    # # 将文件内容拷贝到另一个文件中
    #
    # shutil.copyfile('f1.log', 'f2.log')  # 目标文件无需存在 拷贝文件
    #
    # shutil.copymode('f1.log', 'f2.log')  # 目标文件必须存在 仅拷贝权限。内容、组、用户均不变
    #
    # shutil.copystat('f1.log', 'f2.log')  # 目标文件必须存在           仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
    #
    # shutil.copy('f1.log', 'f2.log')
    # # 拷贝文件和权限
    #
    # shutil.copy2('f1.log', 'f2.log')
    # # 拷贝文件和状态信息
    #
    # shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    # # 目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除            递归的去拷贝文件夹
    #
    # shutil.rmtree('folder1')
    # # 递归的去删除文件
    #
    # shutil.move('folder1', 'folder3')
    # # 递归的去移动文件,它类似mv命令,其实就是重命名。
    #
    #
    # # 将 /data 下的文件打包放置当前程序目录
    # import shutil
    #
    # ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
    #
    # # 将 /data下的文件打包放置 /tmp/目录
    # import shutil
    #
    # ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
    # #
    # # shutil
    # # 对压缩包的处理是调用
    # # ZipFile
    # # 和
    # # TarFile
    # # 两个模块来进行的,详细:
    
    # import tarfile
    #
    # # 压缩
    # t = tarfile.open('/tmp/egon.tar', 'w')
    # t.add('/test1/a.py', arcname='a.bak')
    # t.add('/test1/b.py', arcname='b.bak')
    # t.close()
    
    # 解压
    t = tarfile.open('/tmp/egon.tar', 'r')
    t.extractall('/egon')
    t.close()
    
    # tarfile压缩解压缩
    View Code

    二. 序列化

    一、json 与 pickle 模块
    
    # 1、什么是序列化&反序列化
    
    #序列化:把对象从内存中变成可存储或者传输的类型发生的过程
    
    #反序列化:把这种序列化得到的类型再转变成之前的类型
    
     
    
    # 内存中的数据类型---->序列化---->特定的格式(json格式或者pickle格式)
    # 内存中的数据类型<----反序列化<----特定的格式(json格式或者pickle格式)
    
    # 土办法:
    # {'aaa':111}--->序列化str({'aaa':111})----->"{'aaa':111}"
    # {'aaa':111}<---反序列化eval("{'aaa':111}")<-----"{'aaa':111}"
    
    # 2、为何要序列化
    # 序列化得到的结果=>特定的格式的内容有两种用途
    # 1、可用于存储=》用于存档
    # 2、传输给其他平台使用=》跨平台数据交互
    
    # 强调:
    # 存储用的特定格式:专用的格式=》pickle,只有python可以识别
    # 传输用的特定格式:一种通用、能够被所有语言识别的格式=》json
    
    
    # 3、如何序列化与反序列化
    # 示范1
    # import json
    # # 序列化
    # json_res=json.dumps([1,'aaa',True,False])
    
    # # 反序列化
    # l=json.loads(json_res)
    
     
    
    # 示范2:
    import json
    
    # 序列化的结果写入文件的复杂方法
    # json_res=json.dumps([1,'aaa',True,False])
    #     print(json_res,type(json_res)) # "[1, "aaa", true, false]"
    # with open('test.json',mode='wt',encoding='utf-8') as f:
    #     f.write(json_res)
    
    # 将序列化的结果写入文件的简单方法
    # with open('test.json',mode='wt',encoding='utf-8') as f:
    # json.dump([1,'aaa',True,False],f)
    
    
    # 从文件读取json格式的字符串进行反序列化操作的复杂方法
    # with open('test.json',mode='rt',encoding='utf-8') as f:
    # json_res=f.read()
    # l=json.loads(json_res)
    # print(l,type(l))
    
    # 从文件读取json格式的字符串进行反序列化操作的简单方法
    # with open('test.json',mode='rt',encoding='utf-8') as f:
    # l=json.load(f)
    # print(l,type(l))
    
    
    # json验证: json格式兼容的是所有语言通用的数据类型,不能识别某一语言的所独有的类型
    # json.dumps({1,2,3,4,5})  #集合读不出来
    
    # json强调:一定要搞清楚json格式,不要与python混淆
    # l=json.loads('[1, "aaa", true, false]')
    # l=json.loads("[1,1.3,true,'aaa', true, false]")   #json 不识别单引号
    # print(l[0])
    
    # 了解
    
    #在python解释器2.7与3.6之后都可以json.loads(bytes类型),唯独3.5不可以
    
    # l = json.loads(b'[1, "aaa", true, false]')
    # print(l, type(l))
    
    # with open('test.json',mode='rb') as f:
    # l=json.load(f)
    
    
    # res=json.dumps({'name':'哈哈哈'})   # 中文字符序列化后的形式=>   "u54c8u54c8u54c8"
    # print(res,type(res))
    
     
    
    # 4、猴子补丁
    # 在入口处打猴子补丁
    # import json
    # import ujson
    
    # def monkey_patch_json():
    #   json.__name__ = 'ujson'
    #   json.dumps = ujson.dumps
    #   json.loads = ujson.loads
    
    # monkey_patch_json() # 在入口文件处运行
    
    
    # import ujson as json # 不行,导入的还是ujson
    
     
    
    # 5.pickle模块
    import pickle
    # res=pickle.dumps({1,2,3,4,5})
    # print(res,type(res))
    
    # s=pickle.loads(res)
    # print(s,type(s))
    
     
    
    二、configparser 模块
    
    用configparser 对settings文件进行读取
    
    文件格式如下:
    
    [section1]
    
    k1 =v1
    
    [section2]
    
    k2 : v2
    
    age = 18
    
     
    
    import configparser
    
    # 1、获取sections
    # print(config.sections())
    
    # 2、获取某一section下的所有options
    # print(config.options('section1'))
    
    # 3、获取items
    # print(config.items('section1'))
    
    # 4、获取某一sections下指定的options
    # res=config.get('section1','user')
    # print(res,type(res))
    
     
    
    三、hashlib 模块
    
    # 1、什么是哈希hash
    # hash一类算法,该算法接受传入的内容,经过运算得到一串hash值
    # hash值的特点:
    #I 只要传入的内容一样,得到的hash值必然一样
    #II 不能由hash值返解成内容
    #III 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定
    
    # 2、hash的用途
    # 用途1:特点II用于密码密文传输与验证
    # 用途2:特点I、III用于文件完整性校验
    
    # 3、如何用
    # import hashlib
    #
    # m=hashlib.md5()
    # m.update('hello'.encode('utf-8'))   # windows 系统默认是GBK
    # m.update('world'.encode('utf-8'))
    # res=m.hexdigest() # 'helloworld'
    # print(res)
    
    # 模拟撞库
    # cryptograph='aee949757a2e698417463d47acac93df'
    # import hashlib
    
    # # 制作密码字段
     passwds=[
      'alex3714',
      'alex1313',
      'alex94139413',
      'alex123456',
      '123456alex',
      'a123lex',
      ]
    
    # dic={}
    # for p in passwds:
    #    res=hashlib.md5(p.encode('utf-8'))
    #    dic[p]=res.hexdigest()
    #
    # # 模拟撞库得到密码
    # for k,v in dic.items():
    #    if v == cryptograph:
    #    print('撞库成功,明文密码是:%s' %k)
    #   break
    
    
    # 提升撞库的成本=>密码加盐
    import hashlib
    
    m=hashlib.md5()
    
    m.update('天王'.encode('utf-8'))
    m.update('alex3714'.encode('utf-8'))
    m.update('盖地虎'.encode('utf-8'))
    print(m.hexdigest())
    
     
    
    # 文件的完整性校验
    
    # m.update(文件所有的内容)
    # m.hexdigest()
    
    # with open('a.txt',mode='rb') as f:
    #   f.seek(0,10)
    #   f.read(10) 
    
     
    
    四、subprocess 模块
    
    import subprocess
    
    obj=subprocess.Popen('路径',shell=True,
    stdout=subprocess.PIPE,stderr=subprocess.PIPE,)   # stdout:标准正确输出   pipe:管道  stderr:错误输出
    
    # print(obj)
    # res=obj.stdout.read()
    # print(res.decode('gbk'))
    
    err_res=obj.stderr.read()
    View Code

    三 日志 re

    #
    # 一、logging 模块
    
    import logging
    
    logging.basicConfig(
        # 1、日志输出位置:1、终端 2、文件
        filename='access.log', # 不指定,默认打印到终端
    
        # 2、日志格式
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    
        # 3、时间格式
        datefmt='%Y-%m-%d %H:%M:%S %p',
    
        # 4、日志级别
        # critical => 50
        # error => 40
        # warning => 30
        # info => 20
        # debug => 10
        level=10,
    )
    
    logging.debug('调试debug') # 10
    logging.info('消息info')   # 20
    logging.warning('警告warn')# 30
    logging.error('egon提现失败') # 40
    logging.critical('严重critical') # 50
    
    """
    日志配置字典LOGGING_DIC
    """
    # 1、定义三种日志输出格式,日志中可能用到的格式化串如下
    # %(name)s Logger的名字
    # %(levelno)s 数字形式的日志级别
    # %(levelname)s 文本形式的日志级别
    # %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
    # %(filename)s 调用日志输出函数的模块的文件名
    # %(module)s 调用日志输出函数的模块名
    # %(funcName)s 调用日志输出函数的函数名
    # %(lineno)d 调用日志输出函数的语句所在的代码行
    # %(created)f 当前时间,用UNIX标准的表示时间的浮点数表示
    # %(relativeCreated)d 输出日志信息时,自Logger创建以来的毫秒数
    # %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
    # %(thread)d 线程ID。可能没有
    # %(threadName)s 线程名。可能没有
    # %(process)d 进程ID。可能没有
    # %(message)s用户输出的消息
    
    # 2、强调:其中的%(name)s为getlogger时指定的名字
    standard_format = '%(asctime)s - %(threadName)s:%(thread)d - 日志名字:%(name)s - %(filename)s:%(lineno)d -' 
                      '%(levelname)s - %(message)s'
    
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    test_format = '%(asctime)s] %(message)s'
    
    # 3、日志配置字典
    LOGGING_DIC = {
        'version': 1,  #版本
        'disable_existing_loggers': False,   #禁用现有的记录器
        'formatters': {                      #定制不同的日志格式对象,绑定给不同的handler对象使用
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
            'test': {
                'format': test_format
            },
        },
        'filters': {},                 #过滤日志的对象
        # handlers是日志的接收者,不同的handler会将日志输出到不同的位置
        'handlers': {
            #打印到终端的日志
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志轮转
                'maxBytes': 1024*1024*5,  # 日志大小 5M
                'backupCount': 5,  # 备份计数
                'filename': 'a1.log',  # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
                'encoding': 'utf-8',
                'formatter': 'standard',
            },
            #打印到文件的日志,收集info及以上的日志
            'other': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',  # 保存到文件
                'filename': 'a2.log', # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
                'encoding': 'utf-8',
                'formatter': 'test',
    
            },
        },
        # loggers是日志的产生者,产生的日志会传递给handler然后控制输出
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置  #name是loggers子子典当中的key
            'kkk': {
                'handlers': ['console','other'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
                'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
            },
            '终端提示': {
                'handlers': ['console',], 
                'level': 'DEBUG',  
                'propagate': False,  
            },
            '': {
                'handlers': ['default', ], 
                'level': 'DEBUG',  
                'propagate': False,  
            },
        },
    }
    
    # 4、应用
    
    import settings
    
    # 1、logging是一个包,需要使用其下的config、getLogger,可以如下导入
    # from logging import config
    # from logging import getLogger
    
    # 2、也可以使用如下导入
    import logging.config # 这样连同logging.getLogger都一起导入了,然后使用前缀logging.config.
    
    # 3、加载配置
    logging.config.dictConfig(settings.LOGGING_DIC)
    
    # 4、拿到日志的产生者即loggers来产生日志
    
    # logger1=getLogger('kkk')
    # logger1.info('这是一条info日志')
    
    # logger2=getLogger('终端提示')
    # logger2.info('logger2产生的info日志')
    
    # logger3=getLogger('用户交易')
    # logger3.info('logger3产生的info日志')
    
    # logger4=getLogger('用户常规')  #当getLogger取不到对象是,默认使用key=''的配置
    # logger4.info('logger4产生的info日志')
    
    
    # 5、补充两个重要额知识
    # 1、日志名的命名
    #    日志名是区别日志业务归属的一种非常重要的标识
    
    # 2、日志轮转
    #    日志记录着程序员运行过程中的关键信息,所以不能随意删,为了避免放在同一个日志文件中造成文件过大,加载缓慢,
    #    需要一种设定,超出限制后会将之前的内容写到另一个文件中,当前文件只剩新内容
    #     (实际上老文件是做了重命名用来保存老内容,然后再生成一个新的空文件,命名为原名,保存新内容)
    
    
    # 二、re 模块
    
    
    
    
    import re
    
    # print(re.findall('Aalex',' alexis alex sb')) ==>[] 字符串开头是空格
    #                       
    # print(re.findall('sb',' alexis alexsb sb'))
    #                                      
    # print(re.findall('sb',"""alex
    # alexis
    # alex
    # sb
    # """)) ==> [] 只匹配到换行前的结束字符串
    
    # print(re.findall('sb$',"""alex
    # alexis
    # alex
    # sb
    # """)) ==> ['sb']
    
    # print(re.findall('^alex$','alexis alex sb'))
    # print(re.findall('^alex$','al       ex'))
    # print(re.findall('^alex$','alex'))   ==>混用时必须完全一样才能匹配
    
    # 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
    
    # 1、.:匹配除了
    之外任意一个字符,指定re.DOTALL之后才能匹配换行符
    # print(re.findall('a.b','a1b a2b a b abbbb a
    b a	b a*b'))
    #                                                   a.b
    # ['a1b','a2b','a b','abb','a	b','a*b']
    # print(re.findall('a.b','a1b a2b a b abbbb a
    b a	b a*b',re.DOTALL))
    
    # 2、*:左侧字符重复0次或无穷次,性格贪婪
    # print(re.findall('ab*','a ab abb abbbbbbbb bbbbbbbb'))
    #                                                ab*
    #['a','ab','abb','abbbbbbbb']
    
    # 3、+:左侧字符重复1次或无穷次,性格贪婪
    # print(re.findall('ab+','a ab abb abbbbbbbb bbbbbbbb'))
    #                         ab+
    
    # 4、?:左侧字符重复0次或1次,性格贪婪
    # print(re.findall('ab?','a ab abb abbbbbbbb bbbbbbbb'))
    #                                                ab?
    # ['a','ab','ab','ab']
    
    # 5、{n,m}:左侧字符重复n次到m次,性格贪婪
    # {0,} => *
    # {1,} => +
    # {0,1} => ?
    # {n}单独一个n代表只出现n次,多一次不行少一次也不行
    
    # print(re.findall('ab{2,5}','a ab abb abbb abbbb abbbbbbbb bbbbbbbb'))
    #                                                           ab{2,5}
    # ['abb','abbb','abbbb','abbbbb]
    
    # print(re.findall('d+.?d*',"asdfasdf123as1111111.123dfa12adsf1asdf3"))
    
    
    
    # []匹配指定字符一个
    # print(re.findall('adb','a1111111b a3b a4b a9b aXb a b a
    b',re.DOTALL)) ['a3b', 'a4b', 'a9b']
    # print(re.findall('a[501234]b','a1111111b a3b a4b a9b aXb a b a
    b',re.DOTALL))  ['a3b', 'a4b']
    # print(re.findall('a[0-9a-zA-Z]b','a1111111b axb a3b a1b  a b a
    b',re.DOTALL)) ['axb', 'a3b', 'a1b', ]
    # print(re.findall('a[^0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a
    b',re.DOTALL)) ['a b', 'a
    b'] ^表示非
    # print(re.findall('a[-0-9
    ]b','a-b a0b a1b a8b aXb a b a
    b',re.DOTALL)) ['a-b', 'a0b', 'a1b', 'a8b', 'a
    b']
    View Code
  • 相关阅读:
    Oracle数据库实例的启动及关闭
    SCJP之赋值
    fileupload组件之上传与下载的页面
    commons-fileupload-1.2.1.jar 插件上传与下载
    SCJP读书之知识点:
    filter
    抽象abstract
    搞定导致CPU爆满的“罪魁祸首”
    优化一个小时不出结果的SQL
    最具戏剧性的分析诊断案例——十分钟锁定数据库性能“元凶”
  • 原文地址:https://www.cnblogs.com/lee1225/p/12640420.html
Copyright © 2020-2023  润新知