Python内置模块(re模块、collections模块、time模块、datetime模块)
Python内置模块(re模块、collections模块、time模块、datetime模块)
- 正则表达式小练习
- 取消转义
- re模块
- re模块其他方法
- 正则实战案例
- collections模块
- time模块
- datetime模块
一、正则表达式小练习
# 以数字1-9开头,中间13位或16位数字,以数字0-9或小写字母x结尾 ^[1-9]\d{13,16}[0-9x]$ # 以数字1-9开头,14位数字,把两位数字和0-9x组成一个组,匹配一次或者不匹配 ^[1-9]\d{14}(\d{2}[0-9x])?$ # 以数字1-9开头,中间16位数字,以数字0-9或小写字母想结尾或者以数字1-9开头,后面14位数字 ^([1-9]\d{16}[0-9x]|[1-9]\d{14})$
二、取消转义
在原生的正则表达式中取消转义推荐使用\(每个\只能取消一个字符的转义)
在Python中取消转义推荐使用r'\n\a\t'(也可以使用\)
三、re模块
在Python中要想使用正则必须借助于模块,re就是其中之一
1. 基本操作方法
1)re.findall()
import re re.findall('正则表达式', '待匹配的文本') # 根据正则匹配除所有符合条件的数据 res = re.findall('a', 'eva jason jackson') print(res) # ['a', 'a', 'a'] 结果是一个列表(要么有元素 要么空列表)
2)re.search()
import re res = re.search('正则表达式', '待匹配的文本') # 根据正则匹配到一个符合条件的就结束 res = re.search('a', 'eva jason jackson') print(res) # 结果对象 print(res.group()) # 正则的结果 if res: print(res.group()) else: print('不好意思 没有找到')
如果没有符合条件的数据,那么search返回None,并且使用group会直接报错
3)re.match()
import re res = re.match('a', 'bac') # 根据正则从头开始匹配(文本内容必须在开头匹配上) print(res)if res: print(res.group()) else: print('不好意思 没有找到')
如果没有符合条件的数据 那么match返回None 并且使用group会直接报错
4)re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
四、re模块其他方法
1. re.split()
split 方法按照能够匹配的子串将字符串分割后返回列表
import re # 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 res = re.split('[ab]', 'abcd') # 不一样的地方:中括号里有几个就切几次 print(res) # ['', '', 'cd']
2. re.sub()
类似于字符串类型的replace方法
import re res = re.sub('\d', 'H', 'eva3jason4yuan4', 1) # 替换正则匹配到的内容 print(res) res = re.sub('\d', 'H', 'eva3jason4yuan4') # 不写默认替换所有 print(res)
3. re.subn()
返回元组,并提示替换了几处
import re res = re.subn('\d','H', 'eva3jason4yuan4', 1) print(res) # ('evaHjason4yuan4', 1) res = re.subn('\d', 'H', 'eva3jason4yuan4') print(res) # ('evaHjasonHyuanH', 3)
4. re.compile()(常用)
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
import re regexp_obj = re.compile('\d+') res = regexp_obj.search('absd213j1hjj213jk') res1 = regexp_obj.match('123hhkj2h1j3123') res2 = regexp_obj.findall('1213k1j2jhj21j3123hh') print(res) print(res1) print(res2)
5. re.finditer()(常用)
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
import re res = re.finditer('\d+','ashdklah21h23kj12jk3klj112312121kl131') print([i.group() for i in res])
6. 分组
import re res = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$', '110105199812067023') print(res) print(res.group()) # 110105199812067023 print(res.group(1)) # 10105199812067 print(res.group(2)) # 023
7. 分组优先
findall针对分组优先展示(无名分组)
import re res = re.findall("^[1-9]\d{14}(\d{2}[0-9x])?$", '110105199812067023') print(res) # ['023']
取消分组优先展示(无名分组)
import re res1 = re.findall("^[1-9](?:\d{14})(?:\d{2}[0-9x])?$", '110105199812067023') print(res1)
8. 有名分组
import re res = re.search('^[1-9](?P<xxx>\d{14})(?P<ooo>\d{2}[0-9x])?$', '110105199812067023') print(res) print(res.group()) # 110105199812067023 print(res.group(1)) # 10105199812067 无名分组的取值方式(索引取) print(res.group('xxx')) # 10105199812067 print(res.group('ooo')) # 023
五、正则实战案例
在红牛官网上筛选出所有分公司的信息
import re # 读取带匹配的数据 with open(r'a.txt', 'r', encoding='utf8') as f: data = f.read() # 利用正则匹配数据 # 分公司名称 title_list = re.findall('<h2>(.*?)</h2>', data) # print(title_list) # 分公司地址 address_list = re.findall("<p class='mapIco'>(.*?)</p>", data) # print(address_list) # 分公司邮箱 email_list = re.findall("<p class='mailIco'>(.*?)</p>", data) # print(email_list) # 分公司电话 phone_list = re.findall("<p class='telIco'>(.*?)</p>", data) res = zip(title_list, address_list, email_list, phone_list) for data_tuple in res: print(""" 公司名称:%s 公司地址:%s 公司邮箱:%s 公司电话:%s """ % (data_tuple[0], data_tuple[1], data_tuple[2], data_tuple[3]))
六、collections模块
该模块内部提供了一些高阶的数据类型
1. namedtuple(具名元组)
from collections import namedtuple """ namedtuple('名称',[名字1,名字2,...]) namedtuple('名称','名字1 名字2 ...') """ point = namedtuple('坐标', ['x', 'y']) res = point(11, 22) print(res) # 坐标(x=11, y=22) print(res.x) # 11 print(res.y) # 22 point = namedtuple('坐标', 'x y z') res = point(11, 22, 33) print(res) # 坐标(x=11, y=22, z=33) print(res.x) # 11 print(res.y) # 22 print(res.z) # 33 card = namedtuple('扑克', '花色 点数') card1 = card('♠', 'A') card2 = card('♥', 'K') print(card1) print(card1.花色) print(card1.点数)
2. queue(队列)
import queue # 内置队列模块:FIFO # 初始化队列 q = queue.Queue() # 往队列中添加元素 q.put('first') q.put('second') q.put('third') # 从队列中获取元素 print(q.get()) print(q.get()) print(q.get()) print(q.get()) # 值去没了就会原地等待
3. deque(双端队列)
from collections import deque q = deque([11, 22, 33]) q.append(44) # 从右边添加 q.appendleft(55) # 从左边添加 print(q.pop()) # 从右边取值 print(q.popleft()) # 从左边取值
4. 有序字典
normal_dict = dict([('name', 'jason'), ('pwd', 123), ('hobby', 'study')]) print(normal_dict) # {'hobby': 'study', 'pwd': 123, 'name': 'jason'} from collections import OrderedDict order_dict = OrderedDict([('name', 'jason'), ('pwd', 123), ('hobby', 'study')]) print(order_dict) OrderedDict([('name', 'jason'), ('pwd', 123), ('hobby', 'study')]) order_dict['xxx'] = 111 print(order_dict) OrderedDict([('name', 'jason'), ('pwd', 123), ('hobby', 'study'), ('xxx', 111)]) normal_dict['yyy'] = 222 print(normal_dict) # {'hobby': 'study', 'pwd': 123, 'yyy': 222, 'name': 'jason'}
5. 默认值字典
from collections import defaultdict values = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90] my_dict = defaultdict(list) for value in values: if value > 60: my_dict['k1'].append(value) else: my_dict['k2'].append(value) print(my_dict)
6. 计数器
1)传统方式
res = 'abcdeabcdabcaba' # 统计字符串中每个元素出现的次数 new_dict = {} for i in res: if i not in new_dict: new_dict[i] = 1 else: new_dict[i] += 1 print(new_dict)
2)使用计数器
from collections import Counter # 计数器 res = 'abcdeabcdabcaba' ret = Counter(res) print(ret)
七、time模块
时间三种表现形式:
1)时间戳(秒数)
2)结构化时间(一般是给机器看的)
3)格式化时间(一般是给人看的)
三种时间是可以相互转换的!!!
1. time.sleep() # 原地阻塞指定的秒数
2. time.time() # 获取时间戳时间
3. 格式化时间
import time print(time.strftime('%Y-%m-%d')) # 2021-11-25 print(time.strftime('%Y-%m-%d %H:%M:%S')) # 2021-11-25 11:48:34 print(time.strftime('%Y-%m-%d %X')) # 2021-11-25 11:48:34 print(time.localtime())
4.结构化时间和格式化时间转换
import time print(time.time()) print(time.gmtime(1637840569)) print(time.localtime())
八、datetime模块
1. date.today()和datetime.today()
date年月日 datetime年月日时分秒 time时分秒(MySQL django后期可以)
import datetime print(datetime.date.today()) # 2021-11-25 print(datetime.datetime.today()) # 2021-11-25 12:15:11.969769
2. 获取年月日和星期
import datetime res = datetime.datetime.today() print(res.year) # 2021 print(res.month) # 11 print(res.day) # 25 print(res.weekday()) # 获取星期(weekday星期是0-6) 0表示周一 print(res.isoweekday()) # 获取星期(weekday星期是1-7) 1表示周一
3. timedelta(时间差)
日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象
import datetime ctime = datetime.datetime.today() time_tel = datetime.timedelta(days=3) print(ctime) # 2021-11-25 12:20:48.570489 print(ctime - time_tel) # 2021-11-22 12:21:06.712396 print(ctime + time_tel) # 2021-11-28 12:21:06.712396 ret = ctime + time_tel print(ret - ctime) # 3 days, 0:00:00 print(ctime - ret) # -3 days, 0:00:00
4. 计算生日
import datetime birthday = datetime.date(2022, 2, 3) now_date = datetime.date.today() days = birthday - now_date print('距离生日还有{}天'.format(days))
5. 时区
UTC时间与我们的东八区时间差八个小时
import datetime print(datetime.datetime.now()) # 2021-11-25 19:57:04.114215 print(datetime.datetime.utcnow()) # 2021-11-25 11:57:04.114215