常用模块

blog 328

time和datatime

在Python中,我们想要获取现在的时间,或者是进行时间的运算。那么我们都需要使用到时间模块,在Python中通过以下三种方式来表示时间

  • 时间戳(timestamp) 1970年1月1日距离现在经过的秒数
    • 用于时间间隔的计算
  • 按照某种格式显示的字符串(Format String)
    • 用于展示时间
  • 结构化时间(struct_time):struct_time元组共有9个元素(年、月、日、时、分、秒、一年中第几周、一年中第几天、夏令时) 
    • 用于单独获取时间的某一部分

time模块

time.strftime() 函数用于格式化时间(Format String),返回以可读字符串表示的当地时间,格式由参数 format 决定。

time.time() 获取当前时间的时间戳(timestamp) 即1970年1月1日距今经过的秒数

import time  # 导入内置模块time

print(time.time()) # 获取当前时间的时间戳  1642239329.413331

# 固定格式: %Y 表示年 %m 表示月 %d 表示日 %H 表示小时 %M 分钟 %S 秒
print(time.strftime('%Y-%m-%d %H:%M:%S'))  # 2022-01-15 17:39:39
print(time.strftime('%Y-%m-%d %X')) # 与上述结果一致
print(time.strftime('%Y')) # 2022

# %x是语言环境的"首选"日期格式。
# %X是语言环境的"首选"时间格式。
print(time.strftime('%x %X')) # 01/15/22 17:39:39  
%a    Locale’s abbreviated weekday name.     
%A    Locale’s full weekday name.     
%b    Locale’s abbreviated month name.     
%B    Locale’s full month name.     
%c    Locale’s appropriate date and time representation.     
%d    Day of the month as a decimal number [01,31].     
%H    Hour (24-hour clock) as a decimal number [00,23].     
%I    Hour (12-hour clock) as a decimal number [01,12].     
%j    Day of the year as a decimal number [001,366].     
%m    Month as a decimal number [01,12].     
%M    Minute as a decimal number [00,59].     
%p    Locale’s equivalent of either AM or PM.    (1)
%S    Second as a decimal number [00,61].    (2)
%U    Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0.    (3)
%w    Weekday as a decimal number [0(Sunday),6].     
%W    Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0.    (3)
%x    Locale’s appropriate date representation.     
%X    Locale’s appropriate time representation.     
%y    Year without century as a decimal number [00,99].     
%Y    Year with century as a decimal number.     
%z    Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].     
%Z    Time zone name (no characters if no time zone exists).     
%%    A literal '%' character.

time.localtime() 返回结构化时间(struct_time)

time.gmtime() UTC时间的结构化时间,比北京时间早8个小时

# 获取当前时间的结构化时间
print(time.localtime()) # 什么参数都不传表示获取当前时间的格式化时间
print(time.localtime(1642239329.413331)) # 可以传入一个时间戳 根据时间戳返回结构化时间 

# 结构化时间可以通过下标单独获取某个位置的数值
print(time.localtime()[0]) # 2022年
print(time.localtime()[1]) # 1月
print(time.localtime()[-2]) # 一年中的15天

'''
local_time()返回的结构化时间分析:
time.struct_time(tm_year=2022, tm_mon=1, tm_mday=15, tm_hour=17, tm_min=46, tm_sec=15, tm_wday=5, tm_yday=15, tm_isdst=0)

tm_year 表示年
tm_mon 表示月
tm_mday 表示日
tm_hour 表示时
tm_min 表示分
tm_sec 表示秒
tm_wday 表示周几
tm_yday 表示一年中的第几天
tm_isdst 判断是否是夏令时(dst) 1表示时夏令时(dst) 0表示不是
'''
print(time.gmtime()) # UTC时间的结构化时间,比北京时间早8个小时

datetime模块

datetime.datetime.now() 获取系统的本地时间,包含毫秒

datetime.timedelta() 代表两个时间之间的时间差,两个date或datetime对象相减就可以返回一个timedelta对象

import datetime 
print(datetime.datetime.now()) # 2022-01-15 18:20:24.529485 

# 计算当前时间 + 三天后2小时10分钟的时间

print(datetime.datetime.now() + datetime.timedelta(days=3,hours=2,minutes=10)) # 2022-01-18 20:35:47.375147

# 计算当前时间 - 三天前6小时20分钟的时间
print(datetime.datetime.now() + datetime.timedelta(days=-3,hours=6,minutes=20)) # 2022-01-13 00:46:39.611366

# 计算当前时间 + 一周后的时间 
print(datetime.datetime.now() + datetime.timedelta(weeks=1)) # 2022-01-22 18:28:09.128056

# 时间值的替换
c_time = datetime.datetime.now()
print(c_time) # 2022-01-23 16:17:38.689134
print(c_time.replace(year=2004,month=9,day=25,hour=10,minute=10,second=10)) # 2004-09-25 10:10:10.724957

random模块

Python中的random模块用于生成随机数。

以下为random模块常用方法:

random.random() 生成大于0且小于1之间的随机浮点数

random.randint(x,y) 生成大于x且小于y的随机整数

random.randrange(x,y) 生成大于x且小于y的随机整数。

random.chocie() 返回一个列表、元组、数组的随机项

random.sample(序列,n) 随机从一个序列中,取出n个值。

random.uniform(x,y) 随机生成一个实数,它在x和y范围之内,不包含y

random.shuffle() 随机将序列中的元素打散,类似于洗牌。

import random 

print(random.random()) # (0,1),表示大于0且小于1之间的随机数 ---> float类型
print(random.randint(1,5)) # [1,5 ]大于1且小于5 随机一个整数 ----> int类型
print(random.randrange(1,4)) #[1,4] 大于1且小于4 随机一个整数 ----> int类型

# random.chocie() 返回一个列表、元组或字符串的随机项
res = random.choice([1,[1,2],(10,15),'str']) 
print(res,type(res))  # 从一个序列中随机返回一个数据(类型)。

# random.sample(序列,n) 随机从一个序列取出n个值。
data = (1,2,3,4,5,6)
print(random.sample(data,4))

# random.uniform(x,y),随机生成一个实数,它在x,y范围之内,不包含y
print(random.uniform(10,20))

# random.shuffle() 随机将序列中的元素打散,类似于洗牌
item = [1,2,3,4,5,6,7]
random.shuffle(item)
print(item)



# 随机验证码:
def create_code(number:int=5):
    code = ''
    for i in range(number):
        code += chr(random.randrange(65,91))

    print(code)

create_code()
        

os模块

os模块是与操作系统交流的一个接口。该模块内含有大量的系统操作方法。

import os 

# os.getcwd() 获取当前Python文件所在的工作目录
# print(os.getcwd())  

# os.chdir() 改变当前脚本的工作目录,相当于shell下的cd命令
# os.chdir('/var/www/')
# print(os.getcwd())  # 当前脚本的工作目录就为/var/www/

# os.curdir 返回当前目录
# print(os.curdir)   # value为. 表示当/前目录

# os.curdir 返回当前文件的父级目录
# print(os.pardir)  # value为.. 表示父级目录

# os.mkdir()  生成单级目录,类似于shell中的mkdir dirname
# os.mkdir('/var/www/html/test')   

# os.rmdir()  删除单级目录,若无法删除,则会报错。类似于shell中的rmdir dirname
# os.rmdir('/var/www/html/test')

# os.makedirs() 生成多级目录 例如:test/www/xxx 类似于shell中的 mkdir -p test/www/xxx
# os.makedirs('/var/www/html/test/123/456') 

# os.removedirs()   删除多级目录 这里不再演示 危险

# os.listdir() 列出指定目录下的所有文件和子目录,包括隐藏文件并以列表的方式打印
# print(os.listdir('/var/www/html/'))  

# os.remove() 删除一个文件
# os.remove('/var/www/html/11.txt') 

# os.rename(oldname,newname) 重命名一个文件
# os.rename('/var/www/html/flag.php','/var/www/html/new.php')

# os.stat('path/filename')  获取文件或目录的信息
# print(os.stat('/var/www/html'))

# os.sep 输出当前操作系统特定的路径分隔符 win下为"\\" linux下为"\"
# print(os.sep)  

# os.linesep 输出当前操作系统特定的换行 win下为"\t\n" linux下为"\n"
# print(os.linesep,end='')

# os.pathsep 输出当前操作系统用于分割文件路径的字符串   win下为; linux系统下为;号

# os.name 输出当前操作系统的类型 win为"nt" Linux为"posix"
# print(os.name)

# os.system('shell command') 运行系统命令 直接显示
# os.system('ls')

# os.environ 输出当前操作系统的变量
# print(os.environ)

# os.path.abspath()  返回一个文件的绝对路径 包含文件名
# print(os.path.abspath('/var/www/html/index.php'))

# os.path.split() 分割一个路径 将目录和文件名以元组形式返回
# print(os.path.split('/var/www/html/index.php'))

# os.path.dirname() 获取一个路径 不包含文件名 即os.path.split()分割后的第一个元素
# print(os.path.dirname('/var/www/html/index.pp')) # /var/www/html

# os.path.basename() 返回一个路径的文件名 如果是以\或/结尾,那么就会返回空值
# print(os.path.basename('/var/www/html/index.php'))

# os.path.exists() 判断一个路径是否存在,存在返回True,不存在返回False
# print(os.path.exists('/var/www/html/')) 

# os.path.isabs() 判断一个路径是否是绝对路径
# print(os.path.isabs('/var/www/html'))  

# os.path.isfile() 判断一个路径是否是一个文件
# print(os.path.isfile('/var/www/html/index.php')) 

# os.path.isdir() 判断一个路径是否是一个文件夹
# print(os.path.isdir('/var/www')) # True

# os.path.join() 将多个路径组合起来,如果有一个为绝对路径,则在它前面的组件都会被丢弃
# print(os.path.join('var','www','html')) # var/www/html
# print(os.path.join('/var','www','/etc/html'))  # /etc/html


# os.path.getatime()  返回路径中的文件或者目录的最后存取时间 格式为时间戳
# print(os.path.getatime('/var/www/html/index.php')) 

# os.path.getmtime() 返回路径中的文件或者目录的最后修改时间 格式为时间戳
# print(os.path.getmtime('/var/www/html/'))  

# os.path.getsize()  返回路径的文件或者目录大小

# print(os.path.getsize('/var/www/html/index.php'))
在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。
>>> os.path.normcase('c:/windows\\system32\\')   
'c:\\windows\\system32\\'   
   

规范化路径,如..和/
>>> os.path.normpath('c://windows\\System32\\../Temp/')   
'c:\\windows\\Temp'   

>>> a='/Users/jieli/test1/\\\a1/\\\\aa.py/../..'
>>> print(os.path.normpath(a))
/Users/jieli/test1w

sys模块

import sys
from xmlrpc.client import MAXINT

# sys.argv 获取命令行的参数  第一个元素为文件名称 返回值为列表
# print(sys.argv)

# sys.exit()  退出程序正常退出程序状态码为0
# sys.exit()

# sys.version 获取Python解释器的版本信息
# print(sys.version)

# sys.path 返回模块的查找路径
# print(sys.path)

# sys.platform 返回操作系统的命令
# print(sys.platform)

# 制作进度条效果
'''
[#]
[##]
[###]
[####]
'''

# 指定宽度
print('[%15s]'%'#') # 其中的15表示宽度为15个

# 打印% (两个%%)
print('%%%s'%(100))



# 打印进度条

import re
import time 

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


data_size = 102500
rece_size = 0

while rece_size < data_size:
    time.sleep(0.05) # 模拟网速
    rece_size += 1024
    percent = rece_size / data_size # 1024 / 102500 
    progress(percent,100)


# 实现linux系统的cp功能

import sys
source_file = sys.argv[1]
target_file = sys.argv[2]

with open(r'%s'%source_file,mode='rb') as read_file,\
     open(r'%s'%target_file,mode='wb') as write_file:
        for line in read_file:
            write_file.write(line)


# python3 test.py bg.jpg 123.jpg

shutil模块

from os import symlink
import shutil
from socket import SHUT_RD 

# shutil 是一个高级的文件、文件夹、压缩包处理模块

# copyfileobj()将一个文件的内容copy到一个新文件中
# shutil.copyfileobj(open('old.txt','r'),open('new.txt','w'))


# shutil.copyfile(src_file,dst_file) 拷贝文件
# shutil.copyfile('test.py','123.py')  

# shutil.copymode(src_file,dst_file)  仅赋值src_file文件的权限给dst_file,内容、组、用户均不变
# shutil.copymode('123.py','123.txt')

# shutil.copystat(src, dst) 仅copy文件的信息
# shutil.copystat('f1.log', 'f2.log') 

# shutil.copy(src,dst) 拷贝文件和权限
# shutil.copy('test.py','test.txt')

# shutil.copy2(src,dst) 拷贝文件和状态
# shutil.copy2('test.py','123.py')

# shutil.copytree(src, dst, symlinks=False, ignore=None)
# shutil.copytree('test','new_test',ignore=shutil.ignore_patterns('*.txt','tmp*'))  # ignore表示排除的意思。不copy以*.txt结尾和tmp*开头的

# shutil.rmtree() 递归的去删除文件(夹)
# shutil.rmtree('test')  

# shutil.move(old_dir,new_dir) 递归的去移动文件,类似与shell中的mv命令
# shutil.move('new_test','test')

# shutil.make_archive(base_name, format,...)
# 创建压缩包并返回文件路径,例如:zip、tar 
# base_name即压缩之后生成的文件名,format为压缩包种类“zip”, “tar”, “bztar”,“gztar”,root_dir指定要压缩的路径

#将 /data 下的文件打包放置当前程序目录
# ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')

shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:

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()
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()

json&pickle模块

什么是序列化?

我们把对象(变量)从内存空间中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

内存中的数据类型 ---> 序列化 ----> 特定的格式(json或pickle格式)

内存中的数据类型 <---- 反序列 <----- 特定的格式(json或pickle格式)

为何要有序列化?

序列化得到结果=>特定格式的内容有两种用涂

1、可用于存储 ==> 存档

2、传输给其他平台 ===> 跨平台使用 进行数据的交互

强调: 针对用途的特定格式: 应该是一种通用的是,能够被所有语言都识别的格式。

如何进行序列化与反序列化?

json数据类型与Python数据类型对应关系:

常用模块
截图至egon老师的博客

json模块

import json
# 序列化(将一些格式转换为格式化后的数据)
res = json.dumps(['1',True,False,None,(1,2,3)])
print(res,type(res)) # ["1", true, false, null, [1, 2, 3]] <class 'str'>


# 反序列化 (将一些格式化后的数据,转为原始格式)

res = json.loads('["1", true, false, null, [1, 2, 3]]') # json数据
print(res,type(res))  #  ['1', True, False, None, [1, 2, 3]]

pickle模块

import pickle 

list1 = [1,True,(1,2,3),'hello',{'name':'x1ong'}]

# 序列化
res = pickle.dumps(list1);

print(res,type(res)) # 得到一个byte-

# 反序列化
s = pickle.loads(res)
print(s) # [1, True, (1, 2, 3), 'hello', {'name': 'x1ong'}]

f = open('序列化对象pickle.txt',mode='wb');  # 注意w是写入str,wb是写入byte
f.write(res) # res的值为bytes 
f.close()

xml模块和shelve了解即可,博客地址:https://www.cnblogs.com/linhaifeng/articles/6384466.html#_label6

configparser模块

一般一个程序的配置文件都是以.ini.cfg结尾的,表示是一个程序的配置文件,而我们的configparse模块,可以提取到配置文件的sectionoptions,value等等。

假设有user.ini文件,文件内容如下:

注释符号1: #
注释符号2: ;
[section1]
k1 = v1
k2 : v2   
user = x10ng 
age = 17
gender = male
is_admin = true

[section2]
k1 = v2 
;options = value
;options : value

配置文件的optionsvalue之间可以使用=号间隔或者冒号间隔。而我们的[section]则表示一部分(区域)。

读取操作

import configparser

from sklearn.utils import resample

config = configparser.ConfigParser()
config.read('user.cfg')  # 加载一个配置文件

# 查看配置配置文件中的所有标题(区域)
res = config.sections() # ['section1', 'section2']
print(res) 

# 查看某个标题下的所有option名称

res = config.options('section1')
print(res) # ['k1', 'k2', 'user', 'age', 'gender', 'is_admin']

# 查看某个标题下的option=value,返回的值为key=value
res = config.items('section1')
print(res) # [('k1', 'v1'), ('k2', 'v2'), ('user', 'x10ng'), ('age', '17'), ('gender', 'male'), ('is_admin', 'true')]

# 获取到某一个标题下的option对应的key
res = config.get('section1','user')
print(res,type(res)) # x10ng  ==> string类型
res = config.get('section1','age')
print(res,type(res)) # 17 ===> string类型

# 将获取到的字符'17',转为int类型17
res = int(config.get('section1','age'))
print(res,type(res)) # 17 ===> int类型

# 正常情况下,我们都是使用int()得到的数字进行取出,但是configparser模块,为我们提供了getint()函数,帮我们做这件事

res = config.getint('section1','age')
print(res,type(res)) # 17 ===> int类型

#getboolean() 可以将取到的value转为布尔值
res = config.getboolean('section1','is_admin')
print(res,type(res))  # True ====> bool类型

# 如果一个options的value不是true或者True,则使用了getboolean之后会报错。
# res = config.getboolean('section1','age')
# print(res,type(res))

res = config.getfloat('section1','age') 
print(res,type(res)) # 17.0 ====> float类型

改写操作

import configparser

from matplotlib.pyplot import figimage

config = configparser.ConfigParser()
config.read('user.cfg')

# 删除配置文件中的某一个标题
# config.remove_section('section1')

# 删除配置文件中的某一个标题的配置选项
config.remove_option('section1','user')

# 再次查看section1
# print(config.items('section1')) # 发现user和其对应的value被删除

# 判断是否存在某个标题
print(config.has_section('section1')) # 返回布尔值

# 判断是否存在某个选项
print(config.has_option('section1','user')) 

# 添加一个标题
config.add_section('test')

# 再次查看所有标题
print(config.sections()) # ['section1', 'section2', 'test']

# 在test标题下添加,user=x10ng配置
config.set('test','user','x10ng') 
print(config.get('test','user')) # x10ng

# 最后将修改的内容,写入到文件,完成最后的修改
config.write(open('user.cfg','w'))

hashlib模块的使用

什么是哈希(hash)

hash是一种加密的算法。其中包含了(MD5、SHA1、SHA224、SHA256等等)

hash的特点

  • 字符串一样,得到的hash值也必定一样。
  • 无法通过哈希密文推算到明文
  • 无论校验的文件或字符有多大,得到的hash长度是固定的。

1和3主要针对文件校验方面的hash,而2则是我们在加密密码的时候,使用到的。

hash的加密算法,就好比是一座工厂,工厂会接收你送来的材料,从而进行加工之后,返回对应的hash值。

import hashlib

# 建造hansh的工厂
m = hashlib.md5()

# 为工厂输入原材料(工厂接收的是byte类型)
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))

# 输出加工之后的材料
print(m.hexdigest()) #  fc5e038d38a57032085441e7fe7010b0  helloworld的hash值

code = hashlib.sha256('Admin123'.encode('utf-8'))
print(code.hexdigest())

理论上,hash值是无法被反推出明文的,但是有些网站比如https://www.cmd5.com,数据库中存放了大量加密算法的简单密码和其对应的值。是可以被撞库的。

模拟破解md5加密:

import hashlib

hash_code = 'd8bdfa8342a3731b41b17e48f27250af'

passwords = [
    'Admin',
    '123456',
    'admin',
    'testAdmin',
    'abcd1234',
    'Admin123',
    'testhtml',
    'helloworld'
]
dic = {}
import hashlib
for i in passwords:
    m = hashlib.md5()
    m.update(i.encode('utf-8'))
    res = m.hexdigest()
    dic[i] = res
for k,v in dic.items():
    if v == hash_code:
        print(k)  

re模块(正则表达式)

什么是正则?

正则就是用一些具有特殊函数的符号连接在一起(称为正则表达式)来描述字符串的方法。或者说正则就是用来描述一类事物的规则。在Python中,该规则的使用被内嵌在re模块中,

生活中的正则:

描述符:四条腿

可能会有想到狗猪羊牛马桌子等等。

常见的匹配模式

常用模块

以下为示例:

import re

# /w 匹配字母数字下划线
str1 = 'abcd1234_*&/()^%'
print(re.findall('\w',str1)) # ['a','b','c','d','1','2','3','4','_']

# /W 匹配非字母数字下划线

str2 = 'abcdef12345*/_()&^%$#@!'
print(re.findall('\W',str2)) # ['*','/','(',')','&','^','%','$','#','@','!']

# \s 匹配任意空白字符
str3 = 'abcef\t123\n* $@\t,^\f'
print(re.findall('\s',str3)) # ['\t','\n',' ','\t','\x0c']

# \S 匹配任意非空白字符
str4 = 'abc123, *_()$!@ \n&\f%\t'
print(re.findall('\S',str4)) # ['a','b','c','1','2','3',',','*','_','(',')','$','!','@','&','%']

# \d 匹配任意数字,等价于[0-9]
str5 = 'abc123!@#$%^&*('
print(re.findall('\d',str5)) # ['1','2','3']

# \D 匹配任意非数字字符
str6 = 'a!@#$%^&*(1234535'
print(re.findall('\D',str6)) # ['a','!','@','#','$','%','^','&','*','(']

# \A 匹配字符串的开始
str7 = 'X10ng: study hard'
print(re.findall('\AX10ng',str7)) # ['X10ng']
print(re.findall('\Atest',str7)) # []

# \Z 匹配字符串的结束
str8 = 'X10ng: my name is shuai'
print(re.findall('shuai\Z',str8)) # ['shuai']
str8 = """
my name 
is 
shuai 

"""
# 如果末尾存在换行则匹配到换行前的字符
print(re.findall('shuai\Z',str8)) # []

# 其中的匹配模式\A和\Z推荐使用^和$代替。

# ^匹配以什么开头
str1 = 'helloworld'
print(re.findall('^hello',str1)) # ['hello']

# $匹配以什么结尾
str2 = 'helloworld'
print(re.findall('world$',str2)) # ['world']
import re


# 重复匹配: | . | * | ? | .* | .*? | + | {n,m} |

# . 匹配除\n以外的任意一个字符
print(re.findall('a.b','a1b a*b axb a?b accb a\nb a\tb a b aac bab')) # ['a1b','a*b','axb','a?b','a\tb','a b']

# * 星号的左侧字符重复0次或无穷次 性格贪婪
print(re.findall('ab*','abb abbbbbbbbbb aaaaaaaab a xxab testb')) # ['abb','abbbbbbbbbb','a','a','a','a','a','a','a','ab','a','ab'] 

# ? 问号的左侧字符重复0次或1次 贪婪
print(re.findall('ab?','abb abbbbbbbbbb aaaaaaaab a xxab testb')) #['ab','ab','a','a','a','a','a','a','a','ab','a','ab'] 

# + 加号左侧字符重复1次或无穷次,性格贪婪
print(re.findall('ab+','ab abb a abbbbbbbb aaaaaaaa abc cbab')) #['ab','abb','abbbbbbbb','ab','ab']

# {n,m} 左侧字符重复n次到m次,性格贪婪
print(re.findall('ab{2,5}','ab abb a abbbbbbbb aaaaaaaa abbbbbbc bacacccbbbaaabbb cbab')) #['abb','abbbbb','abbbbb','abbb']
print(re.findall('\d{1}','abc123'))
# {0,} ===> * 
# {0,1} ===> ?
# {1,}  ===> +
# {n} ===> 匹配单个字符n次

# 练习题: 匹配所有数字包含小数在内
# print(re.findall('\d+\.?\d{0,}','asdfasdf123as1.13dfa12adsf1asdf3')) # ['123','1.13','12','1','3']

# .* 默认为贪婪匹配
# print(re.findall('a.*b','aaaaaaaaaa1b1111111111111111b')) # ['aaaaaaaaaa1b1111111111111111b']

# .*? 非贪婪匹配: 推荐使用
# print(re.findall('a.*?b','aaaaaaaaaa1b1111111111111111b')) # ['aaaaaaaaaa1b']

# []
'''
[]中的字符都为普通字符,无需转义,如果[]里面带有普通字符"-",应该将该字符放到[]的开头或末尾
'''
print(re.findall('[0-9]','1234567890')) # ['1','2','3','4','5','6','7','8','9','0']
print(re.findall('[0-3]','1234567890')) # ['1','2','3','0']
print(re.findall('[a-z]','abcdz')) # ['a','b','c','d','z']
print(re.findall('[A-Z]','abABCz')) # ['A','B','C']
print(re.findall('[A-Za-z0-9]','abcABC1234')) # ['a', 'b', 'c', 'A', 'B', 'C', '1', '2', '3', '4']
print(re.findall('a[-1*]b','a1b a*b a-b')) # ['a1b', 'a*b', 'a-b']
print(re.findall('[^a-z]','abc123')) # ['1','2','3'] ^在[]表示除了^后面以外的字符

分享