python之常用模块

1、json&pickle模块
1.1、什么是序列化与反序列化
序列化:
内存中某一类的数据 ————> 特殊的格式

反序列化:
内存中某一类的数据 <———— 特殊的格式
1.2、为何要用序列化
1、存档: 把内存中的数据持久化到硬盘
2、跨平台交互数据

在python中:
存档 => 推荐使用pickle格式
跨平台交互 => 推荐使用json格式
1.3、如何序列化
1.3.1、比较low的序列化与反序列化方式
items = ["圣剑", "蝴蝶", "BKB"]
list_str = str(items)
# 序列化
with open('db.txt'. mode='wt', encoding='utf-8') as f:
    f.write(list_str)
# 反序列化
with open('db.txt'. mode='rt', encoding='utf-8') as f:
    data = f.read()
    items = eval(data)
1.3.2、json的序列化与反序列化方式
优点: 跨平台交互数据
缺点: 无法识别所有的python数据类型

# 方式一:
import json
dict = {'k1': 111, 'k2': 222, 'k3': 333}
# 序列化
res = json.dumps(dict)
print(res, type(res))  # {"k1": 111, "k2": 222, "k3": 333} <class 'str'>

# 反序列化
res1 = json.loads(res)
print(res1, type(res1))  # {'k1': 111, 'k2': 222, 'k3': 333} <class 'dict'>

# 方式二:
import json
dict = {'k1': 111, 'k2': 222, 'k3': 333}
# 序列化
with open('a.json', mode='wt', encoding='utf-8') as fp:
    json.dump(dict, fp)

# 反序列化
with open('a.json', mode='rt', encoding='utf-8') as fp:
    data = json.load(fp)
    print(data, type(data))  # {'k1': 111, 'k2': 222, 'k3': 333} <class 'dict'>
1.3.3、pickle的序列化与反序列化方式
优点: 可以识别所有python数据类型
缺点: 只能用于python中,无法跨平台交互
    
# 方式一:
import pickle
s = {'a', 'b', 'c'}
# 序列化
res = pickle.dumps(s)
print(res, type(res))  # b'\x80\x04\x95\x11\x00\x00\x00\x00\x00\x00\x00\x8f\x94(\x8c\x01b\x94\x8c\x01a\x94\x8c\x01c\x94\x90.' <class 'bytes'>

# 反序列化
res1 = pickle.loads(res)
print(res1, type(res1))  # {'b', 'a', 'c'} <class 'set'>

# 方式二:
import pickle
s = {'a', 'b', 'c'}
# 序列化
with open('b.json', mode='wb') as f:
    pickle.dump(s, f)

# 反序列化
with open('b.json', mode='rb') as f:
    res = pickle.load(f)
    print(res, type(res))  # {'a', 'c', 'b'} <class 'set'>
1.4、猴子补丁
1.4.1、定义
在运行时对方法、类、属性、功能进行修改,把新的代码作为解决方案代替原有的程序,也就是为其打上补丁
1.4.2、使用
很多代码用到 import json,后来发现ujson性能更高,如果觉得把每个文件的import json 改成 import ujson as json成本较高,或者说想测试一下用ujson替换json是否符合预期,只需要在入口加上如下代码:

import json
import ujson
def monkey_patch_json():
    json.__name__ = 'ujson'
    json.dumps = ujson.dumps
    json.loads = ujson.loads
monkey_patch_json()
2、hashlib模块
2.1、hash定义与特点
hash是一种算法(md5、sha256、sha512等),我们为该算法传入文本内容,该算法会计算得到一串hashhash值具备以下三个特点:
    1、如果传入的文本内容一样,并且采用hash算法也一样,那么得到的hash值一定是一样的
    2hash值的长度取决于采用的算法,与传入的文本内容的大小无关
    3hash值不可逆
2.2、hashlib模块的使用
import hashlib
# 第一部分
m = hashlib.md5()
m.update('你好'.encode('utf-8'))
m.update('allen'.encode('utf-8'))
m.update('哈哈'.encode('utf-8'))
res = m.hexdigest()
print(res)

# 第二部分
m1 = hashlib.md5()
m1.update('你好allen'.encode('utf-8'))
m1.update('哈'.encode('utf-8'))
m1.update('哈'.encode('utf-8'))
res1 = m1.hexdigest()
print(res1)

# 结论: 以上两部分得到的结果(hash值)是一致的
2.3、利用hashlib模块实现撞库的案例
import hashlib

password_list = ['allen123', 'allexv587', 'allennb123']

pwd_save_dict = {}


def get_pwd_dict(password_list):
    """
    将猜测的用户名与加密后的hash值整理到字典中
    :param password_list: 
    :return: 
    """
    for pwd in password_list:
        m = hashlib.md5()
        m.update(pwd.encode('utf-8'))
        pwd_save_dict.update({pwd: m.hexdigest()})


get_pwd_dict(password_list)

print(pwd_save_dict)


def broken_pwd(pwd_str, pwd_dict):
    """
    撞库功能
    :param pwd_str: 
    :param pwd_dict: 
    :return: 
    """
    for k, v in pwd_dict.items():
        if v == pwd_str:
            print('原密码是{}'.format(k))
            break
    else:
        print('不存在')


broken_pwd('fca3ca515d9620851de3ee43fbc05b13', pwd_save_dict)
3、time与datetime模块
3.1、时间有三种格式
import time
# 1、时间戳: 秒数
print(time.time())

# 2、格式化的字符串
time.strftime('%Y-%m-%d %H:%S:%M %p')
time.strftime('%Y-%m-%d %X')

# 3、结构化的时间 => 获取时间的某一部分
time.localtime()  # 当地时间 使用更多
time.gmtime()  # 世界标准时间
3.2、时间转换

在这里插入图片描述
在这里插入图片描述

import time

# 时间戳 ---> 格式化的字符串
struct_time = time.localtime(time.time())
res = time.strftime('%Y-%m-%d %H:%M:%S', struct_time)
print(res)  # 2020-07-30 14:40:27

# 格式化的字符串 ---> 时间戳
struct_time = time.strptime('2020-07-30 14:40:27', '%Y-%m-%d %H:%M:%S')
res = time.mktime(struct_time)
print(res)  # 1596091227.0


# asctime([t]) : 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。
# 如果没有参数,将会将time.localtime()作为参数传入。
print(time.asctime())  # Sun Sep 11 00:43:43 2016

# ctime([secs]) : 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为
# None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
print(time.ctime())  # Sun Sep 11 00:46:38 2016
print(time.ctime(time.time()))  # Sun Sep 11 00:46:38 2016

import time

# asctime
res = time.asctime()  # 默认传递time.localtime(),等同于res = time.asctime(time.localtime())
print(res)  # Thu Jul 30 14:47:54 2020

# ctime
res = time.ctime(time.time())
print(res)  # Thu Jul 30 14:47:54 2020

# time.sleep(n)
线程推迟指定的时间运行,单位为秒
time.sleep(2)
3.3、datetime模块
import datetime

res = datetime.datetime.now()
print(res)

# 获取3天后的时间
res = datetime.datetime.now() + datetime.timedelta(days=3)
print(res)

# 获取3小时前的时间
res = datetime.datetime.now() + datetime.timedelta(hours=-3)
print(res)

# 根据时间戳获取年月日
res = datetime.date.fromtimestamp(time.time())
print(res)  # 2020-07-30

# 根据时间戳获取年月日时分秒
res = datetime.datetime.fromtimestamp(time.time())
print(res)  # 2020-07-30 14:58:08.334841

# 替换时间格式化时间中的部分
res = datetime.datetime.now()
print(res)
new_res = res.replace(year=1995, hour=8)
print(new_res)
3.4、利用time模块实现打印进度条
import time

def progress(percent):
    if percent > 1:
        percent = 1
    print('\r[%-50s] %d%%' % ('#' * int(percent * 50), int(percent * 100)), end='')

total_size = 155000
recv_size = 0
while recv_size < total_size:
    time.sleep(0.1)
    recv_size += 1024
    percent = recv_size / total_size
    progress(percent)
4、random模块
4.1、random基本使用
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([1, 'a', ['b', 2, 3]]))  # 1或者'a'或者['b', 2, 3]
print(random.sample([1, 2, 3, ['a', 'b'], ['1', '2']], 2))  # 列表元素任意2个组合
print(random.uniform(1, 3))  # 大于1小于3的小数,如1.927109612082716 
item = [1, 2, 3, 4, 5, 6]
random.shuffle(item)  # 打乱item的顺序,相当于"洗牌"
print(item)
4.2、利用random模块实现验证码
def make_code(count=4):
    """
    生成随机验证码
    :param count:
    :return:
    """
    code_msg = ''
    for x in range(count):
        s1 = str(random.randint(0, 9))
        s2 = chr(random.randint(65, 90))
        code = random.choice([s1, s2])
        code_msg += code
    return code_msg

print(make_code(6))
5、os模块
os模块是与操作系统交互的一个接口

os.getcwd()                          # 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")                  # 改变当前脚本工作目录;相当于shell下cd
os.curdir                            # 返回当前目录: ('.')
os.pardir                            # 获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')     # 可生成多层递归目录
os.removedirs('dirname1')            # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')                  # 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')                  # 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')                # 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()                          # 删除一个文件
os.rename("oldname","newname")       # 重命名文件/目录
os.stat('path/filename')             # 获取文件/目录信息
os.sep                               # 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep                           # 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep                           # 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name                              # 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")            # 运行shell命令,直接显示
os.environ                           # 获取系统环境变量
os.path.abspath(path)                # 返回path规范化的绝对路径
os.path.split(path)                  # 将path分割成目录和文件名二元组返回
os.path.dirname(path)                # 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)               # 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)                 # 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)                  # 如果path是绝对路径,返回True
os.path.isfile(path)                 # 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)                  # 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  # 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)               # 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)               # 返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path)                # 返回path的大小
6、sys模块
6.1、sys基本使用
sys.argv           # 命令行参数List,第一个元素是程序本身路径
sys.exit(n)        # 退出程序,正常退出时exit(0)
sys.version        # 获取Python解释程序的版本信息
sys.maxint         # 最大的Int值
sys.path           # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       # 返回操作系统平台名称
6.2、利用sys.argv实现文件拷贝
# server.py

import sys
import os

args1 = sys.argv[1]
args2 = sys.argv[2]

if os.path.exists(args1):
    with open(r'{}'.format(args1), mode='rb') as fp1, \
            open(r'{}'.format(args2), mode='wb') as fp2:
        for line in fp1:
            fp2.write(line)
print('拷贝成功')

# cmd
python3 server.py 源文件路径 目标文件路径
7、subprocess模块
import subprocess

obj = subprocess.Popen('dir', shell=True,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE
                       )

success_res = obj.stdout.read().decode('gbk')  # 正确信息
print(success_res)

error_res = obj.stderr.read().decode('gbk')  # 错误信息
print(error_res)
8、shutil模块
高级的 文件、文件夹、压缩包 处理模块

# (1) shutil.copyfileobj(fsrc, fdst[, length])
# 将文件内容拷贝到另一个文件中
import shutil
shutil.copyfileobj(open('config.ini', mode='r'), open('xxx.ini', mode='w'))

# (2) shutil.copyfile(src, dst)
# 拷贝文件
import shutil
shutil.copyfile('config.ini', 'xxx.ini')

# (3) shutil.copymode(src, dst)
# 仅拷贝权限。内容、组、用户均不变
import shutil
shutil.copymode('f1.log', 'f2.log')  # 目标文件必须存在

# (4) shutil.copystat(src, dst)
# 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
import shutil
shutil.copystat('f1.log', 'f2.log') #目标文件必须存在

# (5) shutil.copy(src, dst)
# 拷贝文件和权限
import shutil
shutil.copy('f1.log', 'f2.log')

# (6) shutil.copy2(src, dst)
# 拷贝文件和状态信息
import shutil
shutil.copy2('f1.log', 'f2.log')

# (7) shutil.ignore_patterns(*patterns)
# shutil.copytree(src, dst, symlinks=False, ignore=None)
# 递归的去拷贝文件夹
import shutil  
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))  # 目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除

# (8) shutil.rmtree(path[, ignore_errors[, onerror]])
# 递归的去删除文件
import shutil 
shutil.rmtree('folder1')

# (9) shutil.move(src, dst)
# 递归的去移动文件,它类似mv命令,其实就是重命名
import shutil 
shutil.move('folder1', 'folder3')

# (10) shutil.make_archive(base_name, format,...)
# 创建压缩包并返回文件路径,例如:zip、tar
# 创建压缩包并返回文件路径,例如:zip、tar
# base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
# 如 data_bak                       =>保存至当前路径
# 如 /tmp/data_bak =>保存至/tmp/
# format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
# root_dir:	要压缩的文件夹路径(默认当前目录)
# owner: 用户,默认当前用户
# group: 组,默认当前组
# logger: 用于记录日志,通常是logging.Logger对象

# (11) zipfile压缩解压缩
import zipfile
# 压缩
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()
# 解压
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall(path='.')
z.close()

# (12) tarfile压缩解压缩
import tarfile
# 压缩
t=tarfile.open('/tmp/allen.tar','w')
t.add('/test1/a.py',arcname='a.bak')
t.add('/test1/b.py',arcname='b.bak')
t.close()
# 解压
t=tarfile.open('/tmp/allen.tar','r')
t.extractall('/allen')
t.close()
9、shelve模块
shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型

import shelve
f = shelve.open(r'a.txt')
f['info'] = {'name': 'allen', 'age': 18}
print(f['info']['name'])
f.close()
10、xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
11、configparser模块:
# conf.ini
[section1]
user = 'allen'
age : 18
gender = 'male'
salary = 19.5
is_admin = 1

[section2]
user = 'lisi'

import configparser

config = configparser.ConfigParser()
config.read('config.ini')
print(config.sections())  # ['section1', 'section2']

print(config.options('section1'))  # ['user', 'age', 'gender', 'salary', 'is_admin']

print(config.items('section1'))  # [('user', "'allen'"), ('age', '18'), ('gender', "'male'"), ('salary', '19.5'), ('is_admin', '1')]

res = config.get('section1', 'salary')
print(res, type(res))

res = config.getfloat('section1', 'salary')
print(res, type(res))
print(config.getboolean('section1', 'is_admin'))

res = config.getint('section1', 'age')
print(res, type(res))
12、logging模块
12.1、日志级别
CRITICAL = 50  # FATAL = CRITICAL
ERROR = 40
WARNING = 30  # WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0  # 不设置
12.2、默认级别为warning,默认打印到终端
import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

'''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''
12.3、日志级别与配置
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=30,
)

# 二: 输出日志
logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical')

'''
# 注意下面的root是默认的日志名字
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical
'''
12.4、日志配置字典
"""
logging配置
"""

import os

# 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][task_id:%(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': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'test': {
            'format': test_format
        },
    },
    'filters': {},
    'handlers': {
        # 打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        # 打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志轮转
            'formatter': 'standard',
            # 可以定制日志文件路径
            # BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
            # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
            'filename': 'a1.log',  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
        'other': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',  # 保存到文件
            'formatter': 'test',
            'filename': 'a2.log',
            'encoding': 'utf-8',
        },
    },
    'loggers': {
        # logging.getLogger(__name__)拿到的logger配置
        '': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
        '专门的采集': {
            'handlers': ['other',],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}
12.5、使用
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、输出日志
logger1=logging.getLogger('用户交易')
logger1.info('allen转账3亿人民币')

# logger2=logging.getLogger('专门的采集')  # 名字传入的必须是'专门的采集',与LOGGING_DIC中的配置唯一对应
# logger2.debug('专门采集的日志')
13、re模块
13.1、什么是正则表达式
由一系列特殊字符拼接而成的表达式/规则,该表达式用于从一个大字符串中匹配出符合规则的子字符串

import re
13.2、常用模式一览表

在这里插入图片描述

13.3、w、\W
import re
print(re.findall('\w', '你好ls 12*&) _'))  # ['你', '好', 'l', 's', '1', '2', '_']
print(re.findall('\W', '你好jx 12*&) _'))  # [' ', '*', '&', ')', ' '] 
13.4、\s、\S
import re
print(re.findall('\s','你好\rbarry*(_ \t \n'))  # ['\r', ' ', '\t', ' ', '\n']
print(re.findall('\S','你好\rbarry*(_ \t \n'))  # ['你', '好', 'b', 'a', 'r', 'r', 'y', '*', '(', '_']
13.5、\d、\D
import re
print(re.findall('\d', '1234567890 allen *(_'))  # ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
print(re.findall('\D', '1234567890 allen *(_'))  # [' ', 'a', 'l', 'l', 'e', 'n', ' ', '*', '(', '_']
13.6、\A、^
import re
print(re.findall('\Ahel','hello 你好世界 -_- 666'))  # ['hel']
print(re.findall('^hel','hello 你好世界 -_- 666'))  # ['hel']
13.7、\Z、$
import re
print(re.findall('666\Z', 'hello 你好世界 *-_-* \n666'))  # ['666']
print(re.findall('666$', 'hello 你好世界 *-_-* \n666'))  # ['666']
13.8、\n、\t
import re
print(re.findall('\n','hello \n 你好世界 \t*-_-*\t \n666'))  # ['\n', '\n']
print(re.findall('\t','hello \n 你好世界 \t*-_-*\t \n666'))  # ['\t', '\t']
13.9、重复匹配
# . ? * + {m,n} .* .*?
# . 匹配任意字符,除了换行符(re.DOTALL 这个参数可以匹配\n)。
print(re.findall('a.b', 'ab aab a*b a2b a牛b a\nb'))  # ['aab', 'a*b', 'a2b', 'a牛b']
print(re.findall('a.b', 'ab aab a*b a2b a牛b a\nb', re.DOTALL))  # ['aab', 'a*b', 'a2b', 'a牛b']
# ?匹配0个或者1个由左边字符定义的片段。
print(re.findall('a?b', 'ab aab abb aaaab a牛b aba**b'))  # ['ab', 'ab', 'ab', 'b', 'ab', 'b', 'ab', 'b']
# * 匹配0个或者多个左边字符表达式。 满足贪婪匹配 @@
print(re.findall('a*b', 'ab aab aaab abbb'))  # ['ab', 'aab', 'aaab', 'ab', 'b', 'b']
print(re.findall('ab*', 'ab aab aaab abbbbb'))  # ['ab', 'a', 'ab', 'a', 'a', 'ab', 'abbbbb']
# + 匹配1个或者多个左边字符表达式。 满足贪婪匹配  @@
print(re.findall('a+b', 'ab aab aaab abbb'))  # ['ab', 'aab', 'aaab', 'ab']
# {m,n}  匹配m个至n个左边字符表达式。 满足贪婪匹配  @@
print(re.findall('a{2,4}b', 'ab aab aaab aaaaabb'))  # ['aab', 'aaab']
# .* 贪婪匹配 从头到尾.
print(re.findall('a.*b', 'ab aab a*()b'))  # ['ab aab a*()b']
# .*? 此时的?不是对左边的字符进行0次或者1次的匹配,
# 而只是针对.*这种贪婪匹配的模式进行一种限定:告知他要遵从非贪婪匹配 推荐使用!
print(re.findall('a.*?b', 'ab a1b a*()b, aaaaaab'))  # ['ab', 'a1b', 'a*()b']
# []: 括号中可以放任意一个字符,一个中括号代表一个字符
# - 在[]中表示范围,如果想要匹配上- 那么这个-符号不能放在中间.
# ^ 在[]中表示取反的意思.
print(re.findall('a.b', 'a1b a3b aeb a*b arb a_b'))  # ['a1b', 'a3b', 'a4b', 'a*b', 'arb', 'a_b']
print(re.findall('a[abc]b', 'aab abb acb adb afb a_b'))  # ['aab', 'abb', 'acb']
print(re.findall('a[0-9]b', 'a1b a3b aeb a*b arb a_b'))  # ['a1b', 'a3b']
print(re.findall('a[a-z]b', 'a1b a3b aeb a*b arb a_b'))  # ['aeb', 'arb']
print(re.findall('a[a-zA-Z]b', 'aAb aWb aeb a*b arb a_b'))  # ['aAb', 'aWb', 'aeb', 'arb']
print(re.findall('a[0-9][0-9]b', 'a11b a12b a34b a*b arb a_b'))  # ['a11b', 'a12b', 'a34b']
print(re.findall('a[*-+]b', 'a-b a*b a+b a/b a6b'))  # ['a*b', 'a+b']
# - 在[]中表示范围,如果想要匹配上- 那么这个-符号不能放在中间.
print(re.findall('a[-*+]b', 'a-b a*b a+b a/b a6b'))  # ['a-b', 'a*b', 'a+b']
print(re.findall('a[^a-z]b', 'acb adb a3b a*b'))  # ['a3b', 'a*b']
13.10、分组
# () 制定一个规则,将满足规则的结果匹配出来
print(re.findall('(.*?)_all', 'allen_all lily_all lucy_all'))  # ['allen', ' lily', ' lucy']]
# 应用举例:
print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击</a>'))#['http://www.baidu.com']
13.11、或
# | 匹配 左边或者右边
print(re.findall('allen|丽丽|lucy', 'allen李白lucyalllen李白白'))  # ['allen', 'lucy']
print(re.findall('compan(y|ies)','Too many companies have gone bankrupt, and the next one is my company'))  # ['ies', 'y']
print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))  # ['companies', 'company']
# 分组() 中加入?: 表示将整体匹配出来而不只是()里面的内容
13.12、常用方法
# 1 findall 全部找到返回一个列表。
print(re.findall('a', 'allenisaboy'))  # ['a', 'a']
# 2 search 只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
print(re.search('allen|lucy', 'allen lucy lucy 中国'))  # <re.Match object; span=(0, 5), match='allen'>
print(re.search('allen', 'allen lucy lucy 中国').group())  # allen
# 3 match:None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match
print(re.match('allen', 'allen lucy lucy 中国'))  # <re.Match object; span=(0, 5), match='allen'>
print(re.match('allen', 'allen lucy lucy 中国').group())  # allen
# 4 split 分割 可按照任意分割符进行分割
print(re.split('[:,;]', 'allen:lucy,lucy:中国'))  # ['allen', 'lucy', 'lucy', '中国']
# 5 重复使用
obj = re.compile('\d{2}')
print(obj.search('abc123eeee').group())  # 12
print(obj.findall('abc123eeee'))  # ['12'],重用了obj
# import re
ret = re.finditer('\d', 'ds3sy4784a')  # finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x000001CC6B398670>
print(next(ret).group())  # 查看第一个结果
print(next(ret).group())  # 查看第二个结果
print([i.group() for i in ret])  # 查看剩余的左右结果
14、struct模块(解决粘包现象时会使用)
# 该模块可以把一个类型,如数字,转成固定长度的bytes类型
import struct
res = struct.pack('i',12345)
print(res,len(res),type(res))  # 长度是4

res2 = struct.pack('i',12345111)
print(res,len(res),type(res2))  # 长度也是4
 
unpack_res =struct.unpack('i',res2)
print(unpack_res)  # (12345111,)
print(unpack_res[0]) # 12345111
15、paramiko模块
# 该模块可以在本地远程控制linux服务器
import paramiko

# 创建SSH对象
ssh = paramiko.SSHClient()

# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 连接服务器
ssh.connect(hostname='192.168.12.80', port=22, username='root', password='root')

# 执行命令
stdin, stdout, stderr = ssh.exec_command('cd / && ls -al')
# 获取命令结果
result = stdout.read()
# 关闭连接
ssh.close()

print(result.decode('utf-8'))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值