包,模块,常用的标准库,正则语法
一.模块的导入
1.什么是模块
一个py文件就是一个模块
2.模块之间的数据交流
我们可以在任意一个模块中是使用另外一个模块中所有的全局变量(普通变量\函数\类)
如果想要在一个模块中使用另一个模块的内容,必须先导入模块
3.模块的分类
1)系统模块 - 系统已经定义好的模块,程序员可以直接导入使用
2)第三方库模块(其他程序员或者机构定义的的模块) - 需要先下载放到工程中以后再导入使用
3)自定义模块 - (在工程中创建的模块) - 程序员直接导入使用
“”"
4.导入模块
1)导入方式
import 模块名 - 导入指定模块,导入后可以使用这个模块中所有的全局变量,使用方式:模块.变量
from 模块名 import 变量1,变量2,变量3… - 导入指定模块,导入后可以使用这个模块中指定的变量,使用方式:直接用
**from 模块名 import *** - 导入指定模块,导入后可以使用这个模块中所有的全局变量
2)重命名
impor 模块名 as 新模块名 - 导入的时候对模块进行重命明,重命名后通过新模块名来使用模块
from 模块名 import 变量1 as 新变量1,变量2 as 新变量2,变量3… - 导入模块的时候对指定的变量进行重命名
导入方式:
test.py
a = 100
for x in range(10):
pass
def func1():
print('test1: hello!')
b = 10
def func2():
print('test1: func2')
# 1.==========import 模块名=============
import test
print(test.a)
# 2.==========from- import=============
from test import x,func1
from random import randint
from functools import reduce
print(x)
func1()
print(randint(10,20))
# 3.==========from- import *=============
from test import *
print(a)
print(x)
func1()
重命名:
# import test as TS
#
# test = 10
# print(test)
# print(TS.a,TS.x)
# TS.func1()
from test import a as t_a,x as t_x,func1
a ='hello'
print(a,t_a)
二.导入包的原理
1.当代码指定到import 或者 from-import 导入模块的时候,系统会自动进入指定模块,执行这个模块中所有的代码。
2.阻止模块中内容的导入:
如果一个模块中的部分代码不希望在被导入的时候执行,就将这个代码写在 if name == ‘main’ 中。
(每个模块都有一个__name__属性,这个属性保存的是模块名,默认值都是文件名。当我们直接执行某个模块的时候,这个模块
的__name__的值会自动变成__main__, 其他没有被执行的__name__的值都是自己的文件名)
三.函数式编程的标准写法
def func1():
print('显示主页面')
def func2():
print('登录')
def func3():
print('注册')
def main():
# 实现当前模块的功能(功能的实现全靠函数和类)
func1()
func3()
func2()
pass
if __name__ == '__main__':
main()
四.包的使用
1.什么是包
包就是包含__init__.py文件的文件夹
2.怎么使用包中的模块里面的内容
建立包的方式:
方式1:New->python package
方式2:New->Directory->在文件夹下面建立__inti__.py文件
# =======fileManager.py==========
f_name = 'test.txt'
def read_file():
print('读文件')
def write_file():
print('写文件')
import 包.模块
from 包 import 模块
from 包.模块 import 变量1, 变量2, …
# ============1. import 包.模块 ===============
import file.fileManager
file.fileManager.read_file()
import file.fileManager as FM
FM.read_file()
FM.write_file()
# ==============2. from 包 import 模块==============
from file import fileManager
fileManager.read_file()
fileManager.write_file()
# ==============3. from 包.模块 import =============
from file.fileManager import f_name, read_file
print(f_name)
read_file()
3.导入包的原理
导入包的时候,会执行执行包中的__init__.py文件中所有的代码
import file
import file.fileManager
from file import fileManager
4.重复导入
import在导入模块或者包的时候会自动检查对应模块或者包之前是否已经导入过了,如果已经导入不会再重复导入
# include aa.h 在C语言中如果多次出现include引入模块,会产生重复导入的情况
import test1
import test1 # python中使用import引入模块,不会产生重复导入的问题
五.常用的标准库
1.标准库和第三方库
标准库 - python自己提供模块或者包, 用的时候可以直接导入
第三方库 - 由别人提供的模块或者包,需要先安装或者下载后才可以导入
2.常用标准库
os模块 - 提供文件或者文件夹操作的相关功能(例如: 创建文件/文件夹、删除文件/文件夹、…)
sys模块 - 提供系统相关的操作
time模块 - 时间相关操作
datetime模块 - 时间相关的操作
json模块 - json操作
re模块 - 正则表达式相关操作
hashlib - 加密模块
turtle模块 - 画图
“”"
六.time/datetime库
import time
1.time() - 获取当前时间, 返回的是时间戳
2. sleep(时间) - 让程序睡眠指定时间(秒)
3. localtime() - 获取当前的本地时间
4. localtime(时间戳) - 将时间戳对应的时间转换成struct_time(转换我们认识的时间值)
t1 = time.time()
time.sleep(1)
t2 = time.time()
print(t2 - t1)
print(t1, type(t1))
补充:时间戳
时间戳就是当前时间到格林威治时间的1970年1月1日0时0分0秒的时间差, 单位是秒
使用时间戳存储时间的好处:
相比年月日字符串的存储方式,其暂用的存贮空间更小,同时也更易加密存储
t1 = 1596615744.128383 + 20000 # 4个字节
# '2020/8/5/16:31:50' # 17个字节
如果要将时间精确到ms级别,可以使用datetime模块中的datetime函数,使用方法如下所示:
print(time.localtime(t1)) # 只能精确到s
from datetime import datetime
print(datetime.now()) # 可以将时间精确到ms
七.hashlib的使用(加密使用)
import hashlib
1.hashlib模块的使用
hashlib是python3.x中提供的一个标准库,专门用来对数据进行hash加密的,常用的加密算法是: md5、shaxxx
hash算法:
hash算法又叫摘要算法或者离散算法
2.hash(md5)加密的特点
a. 同样的内容使用相同的算法加密之后的结果是一样的
b. 加密之后的结果不可逆
c. 不管原数据的大小或者长度是多少,使用同一种加密算法得到的密文(摘要)的长度是一样的
“”"
3.生成摘要(对数据加密)
1) 根据算法创建hash对象
#hashlib.算法名()
hash = hashlib.md5()
2).使用hash对象对指定的数据加密
hash对象.update(数据) - 对指定的数据加密(这儿的数据必须是二进制数据,类型是bytes)
pw = '123456'
# hash.update(bytes(pw, encoding='utf-8'))
hash.update(pw.encode())
3).获取摘要(获取加密后的密文)
di = hash.hexdigest()
print(di)
4.hash加密的应用2:生成数据摘要,确保原数据的完整性
with open('test.txt', 'rb') as f:
content = f.read()
hash2 = hashlib.md5()
hash2.update(content)
hash2.update('2020-5-8 5:49:0'.encode()) #可以使用两次update,将动态时间也加密
print(hash2.hexdigest())
补充:二进制和字符串之间的相互转换
1) 字符串 -> 二进制
bytes(字符串, encoding=‘utf-8’)
字符串.encode()
2) 二进制 -> 字符串
str(二进制, encoding=‘utf-8’)
二进制.decode(encoding=‘utf-8’)
b = 'acb'.encode()
print(type(b)) #<class 'bytes'>
str_b = str(b, encoding='utf-8')
print(str_b, type(str_b)) # acb <class 'str'>
str_b2 = b.decode(encoding='utf-8')
print(str_b2, type(str_b2)) # acb <class 'str'>
八.正则语法
from re import fullmatch
fullmatch(正则表达式, 字符串) - 判断正则表达式和字符串是否完全匹配,如果不能匹配返回None
1. 什么是正则表达式
正则表达式是一种处理字符串的工具
2.正则的语法(通用)
匹配符号
1) 普通字符
除了在正则中有特殊功能和特殊意义以外的字符就是普通字符。
普通字符在正则表达式中表示这个字符本身
re_str = r'abc'
print(fullmatch(re_str, 'abc'))
2) .- 匹配一个任意字符
re_str = r’.bc’ # 匹配一个长度是3的字符串,后两个字符是bc, 第一个字符是任意字符
print(fullmatch(re_str, '你bc'))
print(fullmatch(re_str, 'bc')) # None
print(fullmatch(re_str, 'abb')) # None
re_str = r'x.x'
print(fullmatch(re_str, 'x=x'))
3) \w - 匹配任意一个数字、字母或者下划线(在ASCII码表中)
re_str = r'\w123'
print(fullmatch(re_str, '9123'))
print(fullmatch(re_str, 'A123'))
print(fullmatch(re_str, '_123'))
print(fullmatch(re_str, '+123')) # None
print(fullmatch(re_str, '胡123')) # 注意:\w可以匹配任意非ASCII码中的字符
4) \d - 匹配任意一个数字字符
re_str = r'\d\dabc'
print(fullmatch(re_str, '23abc'))
print(fullmatch(re_str, '00abc'))
print(fullmatch(re_str, '2Habc')) # None
5) \s - 匹配任意一个空白字符
常见的空白字符:’ ‘、’\n’、’\t’
re_str = r'\d\d\s\d'
print(fullmatch(re_str, '12 3'))
print(fullmatch(re_str, '89\t3'))
print(fullmatch(re_str, '90\n4'))
print(fullmatch(re_str, '12 3')) # None
6) \大写字母(\W, \S, \D)
\大写字母 的功能和 \小写字母 的功能相反
\S - 匹配任意一个非空白字符
\D - 匹配任意一个非数字字符
7) [字符集] - 匹配字符集中的任意一个字符
注意:
**a.**一个[]只能匹配一个字符
b.[字符1-字符2]中两个字符之间的-表示范围:字符1到字符2, 并且要求字符1的编码值必须小于字符2
[abc] - 匹配a或者b或者c
[a-z] - 匹配任意一个小写字母
[A-Z] - 匹配任意一个大写字母
[a-zA-Z] - 匹配任意一个字母
[0-9] - 匹配任意一个数字
[2-9] - 匹配2到9的任意一个数字字符
[\u4e00-\u9fa5] - 匹配任意一个中文字符
re_str = r'[xam]123'
print(fullmatch(re_str, 'a123'))
print(fullmatch(re_str, 'x123'))
print(fullmatch(re_str, 'm123'))
print(fullmatch(re_str, 'b123')) # None
re_str = r'[3-7]abc'
print(fullmatch(re_str, '3abc'))
print(fullmatch(re_str, '7abc'))
print(fullmatch(re_str, '6abc'))
print(fullmatch(re_str, '2abc')) # None
re_str = r'[0-9a-zA-Z_]abc' # abc前面是任意数字、字母或者下划线
print(fullmatch(re_str, '4abc'))
print(fullmatch(re_str, 'Kabc'))
print(fullmatch(re_str, '_abc'))
re_str = r'[\dxy]abc' # abc前面是任意数字或者x或者y
print(fullmatch(re_str, '8abc'))
print(fullmatch(re_str, 'xabc'))
print(fullmatch(re_str, 'yabc'))
8) [^字符集] - 匹配任意一个不在字符集中的字符
[^abc] - 匹配一个不是a、b、c的任意一个字符
[^a-z] - 匹配一个不是小写字母的任意一个字符
re_str = r'[^xy]abc'
print(fullmatch(re_str, 'xabc')) # None
print(fullmatch(re_str, 'yabc')) # None
print(fullmatch(re_str, '9abc'))
print(fullmatch(re_str, 'Kabc'))
print(fullmatch(re_str, '=abc'))
注意:
a. []中的^只有放在最前面的时候才有特殊意义,在其他位置的时候表示字符^本身
b. []中的-只有在两个字符之间的时候才有特殊意义,否则也是表示字符-本身
re_str = r'[x^y]abc'
print(fullmatch(re_str, 'xabc'))
print(fullmatch(re_str, 'yabc'))
print(fullmatch(re_str, '^abc'))
re_str = r'[09-]abc'
print(fullmatch(re_str, '0abc'))
print(fullmatch(re_str, '9abc'))
print(fullmatch(re_str, '-abc'))
print(fullmatch(re_str, '8abc')) # None
匹配次数
1) * - 匹配0次或多次
a* - a匹配0次或者多次
\d* - 任意数字出现0次或多次
[abc]* - [abc]匹配0次或者多次
re_str = r'a*123'
print(fullmatch(re_str, '123'))
print(fullmatch(re_str, 'a123'))
print(fullmatch(re_str, 'aaaaa123'))
re_str = r'\d*abc'
print(fullmatch(re_str, 'abc'))
print(fullmatch(re_str, '4abc'))
print(fullmatch(re_str, '478abc'))
2) + - 匹配1次或多次
re_str = r'\d+abc'
print(fullmatch(re_str, 'abc')) # None
print(fullmatch(re_str, '2abc'))
print(fullmatch(re_str, '7238abc'))
3) ? - 匹配0次或一次
re_str = r'm?123'
print(fullmatch(re_str, '123'))
print(fullmatch(re_str, 'm123'))
print(fullmatch(re_str, 'mm123')) # None
4) {}
{N} - 匹配N次
{M,N} - 匹配M到N次
{M,} - 匹配至少M次
{,N} - 最多N次
print(fullmatch(r'\d{3}abc', '890abc'))
print(fullmatch(r'x{3,5}abc', 'xxxabc'))
print(fullmatch(r'x{3,5}abc', 'xxxxabc'))
print(fullmatch(r'x{3,5}abc', 'xxxxxabc'))
print(fullmatch(r'x{3,}abc', 'xxxxxxxxxabc'))
print(fullmatch(r'x{3,}abc', 'xxabc')) # None
print(fullmatch(r'x{,3}abc', 'abc'))
print(fullmatch(r'x{,3}abc', 'xxabc'))
print(fullmatch(r'x{,3}abc', 'xxxabc'))
print(fullmatch(r'x{,3}abc', 'xxxxabc')) # None
3. 贪婪和非贪婪
当匹配次数不确定的时候,匹配模式分为贪婪和非贪婪两种:
贪婪: 在能匹配成功的前提下,次数尽可能多的匹配(越多越好)。 默认情况下都是贪婪
非贪婪: 在能匹配成功的前提下,次数尽可能少的匹配(越少越好)。在不确定的匹配次数后加?就是非贪婪的
*?, +?, ??, {M,N}? , {M,}?, {,N}?
1)fullmatch贪婪和非贪婪没有区别
from re import fullmatch, search, findall
re_str = '.*?abc'
print(fullmatch(re_str, 'xyxabc'))
print(fullmatch(re_str, 'xyxabc123abc'))
2)search的用法
from re import fullmatch, search, findall
re_str = r'\d\d'
print(search(re_str, 'abc34xyz89==')) # <re.Match object; span=(3, 5), match='34'>
print(search(r'.*abc', '你好920abc==-nmabc2323')) # 5, 12
# <re.Match object; span=(0, 16), match='你好920abc==-nmabc'> #贪婪尽可能多的匹配
print(search(r'.*?abc', '你好920abc==-nmabc2323'))
# <re.Match object; span=(0, 8), match='你好920abc'> #非贪婪匹配长度短于贪婪
print(search(r'a\d+', 'shdfa8892jskks')) # a8、a88、a889、a8892
# <re.Match object; span=(4, 9), match='a8892'> #贪婪尽可能多的匹配
print(search(r'a\d+?', 'shdfa8892jskks'))
# <re.Match object; span=(4, 6), match='a8'> #非贪婪匹配长度短于贪婪
4. 检测符号
检测类的符号只做字符的检测不会进行匹配
1)\b - 检测是否是单词边界(单词边界就是任何可以区分出两个不同单词的符号,比如:空白字符、标点符号、字符串开头和字符串结尾)
re_str = r'abc\b123' # re_str = r'abc123'
print(fullmatch(re_str, 'abc 123')) # None
print(fullmatch(re_str, 'abc123')) # None
re_str = r'abc.\b123' # re_str = r'abc.123'
print(fullmatch(re_str, 'abc,123'))
print(fullmatch(re_str, 'abc 123'))
re_str = r'\b\d{3}\b'
print(findall(re_str, 'ahs345ksdj897四季花海345jsks345, 345, 894集 899 288 三等奖'))
# ['345', '899', '288']
2) ^ - 检测是否是字符串开头
re_str = r'\d{3}'
print(findall(re_str, 'ahs345ksdj897四季花海345jsks345, 345, 894集 899 288 三等奖'))
# ['345', '897', '345', '345', '345', '894', '899', '288']
re_str = r'^\d{3}'
print(findall(re_str, '7829ahs345ksdj897四季花海345jsks345, 345, 894集 899 288 三等奖'))
# ['782']
3) $ - 检测是否是字符串结尾
re_str = r'\d{3}$'
print(findall(re_str, '7829ahs345ksdj897四季花海345jsks345, 345, 894集 899 288 三等奖345'))
# ['345']
5. 分支 - |
| - 在正则中表示或者
正则表达式1|正则表达式2|正则表达式3|… - 让字符串先和第一个正则进行匹配如果失败再和第二个正则匹配,以此类推…
写一个正则能够匹配3个数字或者3个字母
re_str = r'\d{3}|[a-zA-Z]{3}'
print(fullmatch(re_str, '234'))
print(fullmatch(re_str, 'jsK'))
练习: 写一个正则能匹配的字符串是: abc后面是三个数字或者两个大写字母
# 能够匹配成功: abc234、abcHK
re_str = r'abc\d{3}|abc[A-Z]{2}'
# re_str = r'abc\d{3}|[A-Z]{2}'
print(fullmatch(re_str, 'abc342'))
print(fullmatch(re_str, 'abcKL'))
6. 分组 - ()
1)把正则的部分内容看成一个整体,进行操作
re_str = r'abc(\d{3}|[A-Z]{2})' #和r'abc\d{3}|abc[A-Z]{2}'一个意思
print(fullmatch(re_str, 'abc234'))
练习: 写一个正则能够匹配一个字符串是两个数字三个字母这种结构不断重复的字符串
# 67hsj89klo89jju90kkl
# 78ksj
# 89jsk90uwu
re_str = r'(\d{2}[a-zA-Z]{3})+'
print(fullmatch(re_str, '67hsj89klo89jju90kkl'))
print(fullmatch(re_str, '89jsk90uwu'))
2) 分组和\N配合使用来控制匹配内容重复
re_str = r'abc(\d{2})=\1'
print(fullmatch(re_str, 'abc78=78'))
# re_str = r'abc\1(\d{2})' # re.error: invalid group reference 1 at position 4
# print(fullmatch(re_str, 'abc78=78'))
# re_str = r'abc(\d{2})=\2' # re.error: invalid group reference 2 at position 12
# print(fullmatch(re_str, 'abc78=78'))
re_str = r'([a-z]{3})(\d{2})\2\1\1' # \1表示第一个分组内容,\2表示第二个分组内容
print(fullmatch(re_str, 'xyz3434xyzxyz'))
re_str = r'([a-z]{3})(\d{2})\1{3}' #\1{3}表示重复第一个分组内容三次
print(fullmatch(re_str, 'mna99mnamnamna'))
re_str = r'(a(\d{2}))\1=\2' # 最外面的括号表示第一个分组,内部的表示第二个分组
print(fullmatch(re_str, 'a34a34=34')) #<re.Match object; span=(0, 9), match='a34a34=34'>
print(findall(r'a(\d{2})', 'a89几十块的78晋级赛a2923=skska90=-aksa78, 89世纪东方11')) # ['89', '29', '90', '78']
九. re模块
import re
1.compile(正则表达式) - 编译正则表达式创建一个正则表达式对象
re_obj = re.compile(r'\d{3}')
# re.fullmatch(正则表达式, 字符串)
# 正则对象.fullmatch(字符串)
print(re_obj.fullmatch('799'))
2.匹配
1) fullmatch(正则表达式, 字符串) - 完全匹配,查看整个字符串是否和正则表达式匹配; 匹配成功返回匹配对象,失败返回None
2) match(正则表达式,字符串) - 匹配字符串开头, 查看字符串的开头是和正则匹配;匹配成功返回匹配对象,失败返回None
re_str = r'\d{3}'
print(re.fullmatch(re_str, '789'))
print(re.fullmatch(re_str, '789ass')) # None
print(re.match(re_str, '789是快递费akskk'))
3)匹配对象(Match对象)
re_str = r'(\d{3})([a-z]{2})'
result = re.match(re_str, '234kl数据库是否')
print(result) # <re.Match object; span=(0, 5), match='234kl'>
a.获取匹配到的字符串
匹配对象.group() - 获取整个正则匹配到的结果
匹配对象.group(N) - 获取正则中第N个分组匹配到的结果
print(result.group()) # 234kl
print(result.group(1)) # 234
print(result.group(2)) # kl
b.获取匹配到的字符串在原字符串中的位置
匹配对象.span() - 获取整个正则匹配到的结果在原字符串中的位置
匹配对象.group(N) - 获取正则中第N个分组匹配到的结果在字符串中的位置
print(result.span()) # (0, 5)
print(result.span(1)) # (0, 3)
print(result.span(2)) # (3, 5)
c.获取原字符串
print(result.string) # 234kl数据库是否
3查找
1)search(正则表达式, 字符串) - 在字符串中获取第一个满足正则表达式的子串,如果找到了返回匹配对象,找不到返回None
print(re.search(r'\d{3}', 'ahdfjhj红色经典23sjd是')) # None
print(re.search(r'\d{3}', 'ahdfjhj红283色经典23sjd是')) # <re.Match object; span=(8, 11), match='283'>
print(re.search(r'\d{3}', 'ahdfj0192hj红283色经典23sjd是')) # <re.Match object; span=(5, 8), match='019'>
2) findall(正则表达式, 字符串) - 获取字符串中所有满足正则表达式的子串;返回一个列表,列表中的元素就是匹配到的子串
a.正则中没有分组 - 列表中的元素就是整个正则匹配到的子串
re_str = r'\d{3}[A-Z]{2}'
str1 = '你好234KL=skks8920PM坚实的-1a891NB坚实的'
result = re.findall(re_str, str1)
print(result) # ['234KL', '920PM', '891NB']
b.正则中有一个分组 - 匹配成功后将分组匹配到的子串作为列表元素
re_str = r'(\d{3})[A-Z]{2}'
str1 = '你好234KL=skks8920PM坚实的-1a891NB坚实的'
result = re.findall(re_str, str1)
print(result) # ['234', '920', '891']
c. 正则中有多个分组 - 匹配成功后每个匹配结果是一个元组,元组中的元素是每个分组匹配到内容,将元组作为列表的元素
re_str = r'(\d{2})-([A-Z]{2})'
str1 = '你好23-KL=skks8920-PM坚实的-1a891NB坚实的'
result = re.findall(re_str, str1)
print(result) # [('23', 'KL'), ('20', 'PM')]
3) finditer(正则表达式, 字符串) - 获取字符串中所有满足正则表达式的子串;返回一个迭代器,迭代器中的元素是匹配对象
re_str = r'(\d{2})-([A-Z]{2})'
str1 = '你好23-KL=skks8920-PM坚实的-1a891NB坚实的'
result = re.finditer(re_str, str1)
print(result) # <callable_iterator object at 0x108922f50>
print(list(result)) #[<re.Match object; span=(2, 7), match='23-KL'>, <re.Match object; span=(14, 19), match='20-PM'>]
4.字符串替换
sub(正则表达式,新字符串, 原字符串) - 将原字符串中所有满足正则表达式的子串全部替换成新字符串
练习:将字符串中所有数字字符都替换成’+'
str1 = '减税降费823世纪东方0kJhjs=139jksd01nkk'
result = re.sub(r'\d', '+', str1) #一个数字替换成一个+
print(result) # 减税降费+++世纪东方+kJhjs=+++jksd++nkk
str1 = '减税降费823世纪东方0kJhjs=139jksd01nkk'
result = re.sub(r'\d+', '+', str1) #多个数字替换成一个+
print(result) # '减税降费+世纪东方+kJhjs=+jksd+nkk'
练习:替换语句中的不良用语
sentence = '你丫是傻叉吗? 我操你大爷的. Fuck you.'
purified = re.sub('[操肏艹草曹]|fuck|shit|傻[比屄逼叉缺吊屌]|煞笔',
'*', sentence, flags=re.IGNORECASE)
print(purified) # 你丫是*吗? 我*你大爷的. * you.
5.字符串切割
split(正则表达式, 字符串) - 将字符串中满足正则表达式的子串作为切割点对字符串进行切割
poem = '床前明月光,疑是地上霜。举头望明月,低头思故乡。'
result = re.split(r'[,。]', poem)
print(result) #['床前明月光', '疑是地上霜', '举头望明月', '低头思故乡', '']
十.忽略大小写和多行匹配
from re import fullmatch, IGNORECASE
1.忽略大小写:在正则表达式的最前面加 (?i)
re_str = r'(?i)abc' #方法1
print(fullmatch(re_str, 'abc'))
print(fullmatch(re_str, 'ABC'))
print(fullmatch(re_str, 'Abc'))
print(fullmatch(r'abc', 'ABC', flags=IGNORECASE)) #方法2
2. 单行匹配: .能够匹配换行符的匹配模式, 在正则的最前面加 (?s)
默认是多行匹配: .不能匹配换行符
re_str = r'a.+b'
print(fullmatch(re_str, 'a+\nb')) # None
re_str = r'(?s)a.+b'
print(fullmatch(re_str, 'a+\nb')) # <re.Match object; span=(0, 4), match='a+\nb'>
3.符号的转义
在在正则中有特殊功能或者特殊意义的符号前加**,让它的功能消失就表示符号本身**
re_str = r'\d\d\.\d\d'
print(fullmatch(re_str, '23.89'))
print(fullmatch(re_str, '23+89')) # None
re_str = r'\(\d\d\)'
print(fullmatch(re_str, '(34)'))
re_str = r'\[\d\d\]'
print(fullmatch(re_str, '[89]'))
re_str = r'\d\+'
print(fullmatch(re_str, '3+'))
# 在[]外面独立存在有特殊功能的符号,在[]中功能会直接消失
re_str = r'[=a+.]123'
print(fullmatch(re_str, 'a123'))
print(fullmatch(re_str, '=123'))
print(fullmatch(re_str, '.123'))
print(fullmatch(re_str, '+123'))
print(fullmatch(re_str, '~123')) # None
re_str = r'[\\d]123'
print(fullmatch(re_str, '\\123'))
print(fullmatch(re_str, 'd123'))
re_str = r'[a\-z]' # [az-]\[-az]
print(fullmatch(re_str, 'a'))
print(fullmatch(re_str, '-'))
print(fullmatch(re_str, 'z'))
print(fullmatch(re_str, 'm')) # None