模块pro
软件开发目录规范
目录规范并没有固定的要求 只要符合清晰可读即可
bin文件夹
存放启动文件(如果启动文件很少,或者就那么一个,可以直接放在根目录上)
start.py
conf文件夹
存放一系列配置文件
settings.py
lib文件夹
存放公共的一些功能
common.py
db文件夹
存放数据相关类型
userinfo.json
log文件夹
存放日志相关文件
log.txt
core文件夹
存放核心代码文件
src.py
readme文件
存放说明相关信息
requirements.txt
存放项目所需要的第三方模块及版号,文件名固定
re正则模块
-
正则表达式
利用一些特殊的符号的组合,去字符串中筛选出符合条件的数据
""" 1.必须是11位 2.必须是纯数字 3.必须符合手机号的排布 15 16 18 19 """ 方式一:代码形式 # phone = input('请输入你的手机号>>>:').strip() # if len(phone) == 11: # if phone.isdigit(): # if phone.startswith('15') or phone.startswith('16') or phone.startswith('18') or phone.startswith('19'): # print('手机号正确') # else: # print('格式不对') # else: # print('手机号必须是纯数字') # else: # print('必须是11位') 方式二:正则表达式 import re phone_number = input('请输入您的电话号码>>>') if re.match('^(15|16|18|19)[0-9]{9}$',phone_number): print('电话号码合法') else: print('电话号码不合法') -
字符组
特征是用中括号括起来 字符串默认只能单个单个字符匹配 [0-9a-zA-Z] # 匹配数字及大小写英文字符 -
特殊符号
符号 描述 . 匹配除换行符以外的任意字符 \d 匹配数字 ^ 匹配开头 $ 匹配结尾 a|b 匹配字符a或者匹配字符b () 匹配括号内的表达式,同时也代表一个组 [...] 匹配字符组中的字符 [^...] 取反,匹配除了字符组中字符之外的所有字符 - ^abc$ # 精准查找
-
量词
1.表达式在没有量词修饰的情况下都是单个单个匹配的
2.量词必须结合(字符串、特殊符号)一起使用 不能单独出现
3.量词只影响前面的一个表达式(ab+,只影响b)
4.量词默认遵循贪婪匹配
| 符号 | 描述 |
|---|---|
| * | 零次或多次 |
| + | 一次或多次 |
| ? | 零次或一次 |
| n次 | |
| n次或更多次 | |
| n次到m次 |
- 贪婪匹配与非贪婪匹配
# 待匹配的字符
<script>123</script>
# 正则表达式
<.*> '''默认贪婪匹配 尽可能多的匹''' # <script>123</script>
# 将贪婪变为非贪婪 只需要在量词的后面加问号即可
<.*?> '''非贪婪匹配 尽可能少的匹 结束条件由左右两边决定'''
- re模块的基本使用
在python想要使用正则就必须借助模块,而re就是其中之一
import re
re.findall('正则表达式','待匹配文本') # 结果是一个列表(要么有元素 要么就是一个空列表)
re.search('正则表达式','待匹配文本') # 结果是一个对象
res = re.search('正则表达式','待匹配文本') # 如果没有匹配到,返回None
res.group() # 未匹配到数据会报错
re.match('a','abac') # 根据正则规则从头匹配,开头没有则终止
同样的,直接使用返回一个对象,使用.group可以实现结果再现
注,search与match一般都会与if语句连用,避免匹配不到数据时,报错
# if res:
# print(res.group())
# else:
# print('不好意思 没有找到')
- re模块的其他方法
import re
按照正则切分字符串split
res = re.split('[ab]','abcd')
print(res) # ['', '', 'cd'] # 返回结果是一个列表
定点替换sub
res = re.sub('\d','H','eva3jason4yuan4',1) # 替换正则匹配到的内容
print(res) # evaHjason4yuan4 返回的仍旧是字符串
res = re.sub('\d','H','eva3jason4yuan4',1) # 替换正则匹配到的所有内容
定点替换plus subn
res = re.subn('\d','H','eva3jason4yuan4',1)
print(res) # ('evaHjason4yuan4', 1) # 返回元组,第二个参数注明替换次数
正则规则提前定义好compile,后面重复引用
regexp_obj = re.compile('\d+')
# res = regexp_obj.search('absd213j1hjj213jk')
# res1 = regexp_obj.match('123hhkj2h1j3123')
# res2 = regexp_obj.findall('1213k1j2jhj21j3123hh')
# print(res,res1,res2)
findall升级版,finditer
res = re.finditer('\d+','ashdklah21h23kj12jk3klj112312121kl131')
print([i.group() for i in res]) # 结果形式上来看返回的是一个对象,需要便利才能全部输出,这样通findall相比,节省不少空间
()实现分组
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
?:无名分组
# findall针对分组优先展示 无名分组
# res = re.findall("^[1-9]\d{14}(\d{2}[0-9x])?$",'110105199812067023')
# print(res) # ['023']
# 取消分组优先展示 无名分组
# res1 = re.findall("^[1-9](?:\d{14})(?:\d{2}[0-9x])?$",'110105199812067023')
# print(res1)
?P<xxx>有名分组
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
- 利用re模块实现一个爬虫小案例
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模块
- namedtuple(具名元组)
'''格式
namedtuple('名称',[名字1,名字2,...])
namedtuple('名称','名字1 名字2 ...')
'''
from collections import namedtuple
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.点数)
- deque双端队列
# 队列模块
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()) # 值取没了就会原地等待
# 双端队列
from collections import deque
q = deque([11,22,33])
q.append(44) # 从右边添加
q.appendleft(55) # 从左边添加
print(q.pop()) # 从右边取值
print(q.popleft()) # 从做边取值
- OrderedDict有序字典
# 普通字典在定义结束后,展现出来的结果可能会与定义时的顺序有出入
from collections import OrderedDict
order_dict = OrderedDict([('name', 'jason'), ('pwd', 123), ('hobby', 'study')])
print(order_dict) # OrderedDict([('name', 'jason'), ('pwd', 123), ('hobby', 'study')])
- defaultdict默认字典
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)
- Counter计数器
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)
from collections import Counter # 计数器
ret = Counter(res)
print(ret)
time与datetime模块
- time模块
时间的三种表现形式:
1.时间戳(秒数)---timestamp
2.结构化时间(给机器看的)---strut_time
3.格式化时间(给人看的)---format time
1.time.sleep() # 原地阻塞多少秒
2.time.time() # 获取时间戳1970.1.1
针对结构化时间:struct_time元组共有9个元素,返回struct_time的函数主要有gmtime(),localtime(),strptime()
# 格式化时间
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.gmtime(11111111111))

# 结构化时间
print(time.strptime('2021-11-25 19:00:37','%Y-%m-%d %X'))
# time.struct_time(tm_year=2021, tm_mon=11, tm_mday=25, tm_hour=19, tm_min=0, tm_sec=37, tm_wday=3, tm_yday=329, tm_isdst=-1)
| 属性 | 值 |
|---|---|
| tm_year(年) | 比如2021 |
| tm_mon(月) | 1 - 12 |
| tm_mday(日) | 1 - 31 |
| tm_hour(时) | 0 - 23 |
| tm_min(分) | 0 - 59 |
| tm_sec(秒) | 0 - 61 |
| tm_wday(weekday) | 0 - 6(0表示周日) |
| tm_yday(一年中的第几天) | 1 - 366 |
| tm_isdst(是否是夏令时) | 默认为-1 |
- datetime模块
import datetime
print(datetime.date.today()) # 2021-11-25
print(datetime.datetime.today()) # 2021-11-25 12:15:11.969769
print(datetime.datetime.utcnow()) # 2021-11-25 04:25:33.579310
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表示周一
"""时间差(timedelta)"""
datetime.timedelta(days,month...)
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
xprint(ctime + time_tel) # 2021-11-28 12:21:06.712396
"""
日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象
"""

浙公网安备 33010602011771号