1.模块
a.定义:本质就是.py结尾的python文件,逻辑上组织python代码,实现某种功能。例:文件名test.py-->模块名test。
b.导入方法:imort moduname
from mdname import *
from mdname import name as rename
...
c.import本质(路径搜索和搜索路径)
d.导入优化:from mdname import test
e.模块分类:标准库内的模块、开源模块、自定义模块。
2.time &datetime模块
Python的时间模块主要有两个:time和datetime。
2.1 time模块
Python的time模块实现主要调用C库,所以各个平台可能有所不同。time模块表示时间的有三种类型:
(1)timestamp 时间戳,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。返回时间戳方式的函数主要有time(),clock()等;
(2)struct_time 时间元组,共有九个元素。返回struct_time的函数主要有gmtime(),localtime(),strptime();
tm_year 2018 tm_mon 1 到 12 tm_mday 1 到 31 tm_hour 0 到 23 tm_min 0 到 59 tm_sec 0 到 61 (60或61 是闰秒) tm_wday 0到6 (0是周一) tm_yday 1 到 366(儒略历) tm_isdst -1, 0, 1, -1是决定是否为夏令时的旗帜
(3)format time 格式化时间,自定义格式和固定格式。相当于把时间转换成可读性比较高的字符串。
补充:UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。中国北京时间(东八区)为UTC+8。DST(Daylight Saving Time)为夏令时。
1 #_*_coding:utf-8_*_ 2 import time 3 4 5 # print(time.clock()) #返回处理器时间,3.3开始已废弃 , 改成了time.process_time()测量处理器运算时间,不包括sleep时间,不稳定,mac上测不出来 6 # print(time.altzone) #返回与utc时间的时间差,以秒计算 7 # print(time.asctime()) #返回时间格式"Fri Aug 19 11:14:16 2016", 8 # print(time.localtime()) #返回本地时间 的struct time对象格式 9 # print(time.gmtime(time.time()-800000)) #返回utc时间的struc时间对象格式 10 11 # print(time.asctime(time.localtime())) #返回时间格式"Fri Aug 19 11:14:16 2016", 12 #print(time.ctime()) #返回Fri Aug 19 12:38:29 2016 格式, 同上 13 14 15 16 # 日期字符串 转成 时间戳 17 # string_2_struct = time.strptime("2016/05/22","%Y/%m/%d") #将 日期字符串 转成 struct时间对象格式 18 # print(string_2_struct) 19 # # 20 # struct_2_stamp = time.mktime(string_2_struct) #将struct时间对象转成时间戳 21 # print(struct_2_stamp) 22 23 24 25 #将时间戳转为字符串格式 26 # print(time.gmtime(time.time()-86640)) #将utc时间戳转换成struct_time格式 27 # print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将utc struct_time格式转成指定的字符串格式 28 29 #时间加减 30 import datetime 31 32 # print(datetime.datetime.now()) #返回 2016-08-19 12:47:03.941925 33 #print(datetime.date.fromtimestamp(time.time()) ) # 时间戳直接转成日期格式 2016-08-19 34 # print(datetime.datetime.now() ) 35 # print(datetime.datetime.now() + datetime.timedelta(3)) #当前时间+3天 36 # print(datetime.datetime.now() + datetime.timedelta(-3)) #当前时间-3天 37 # print(datetime.datetime.now() + datetime.timedelta(hours=3)) #当前时间+3小时 38 # print(datetime.datetime.now() + datetime.timedelta(minutes=30)) #当前时间+30分 39 40 41 # 42 # c_time = datetime.datetime.now() 43 # print(c_time.replace(minute=3,hour=2)) #时间替换
对应格式:
1 %a 本地(locale)简化星期名称 2 %A 本地完整星期名称 3 %b 本地简化月份名称 4 %B 本地完整月份名称 5 %c 本地相应的日期和时间表示 6 %d 一个月中的第几天(01 - 31) 7 %H 一天中的第几个小时(24小时制,00 - 23) 8 %I 第几个小时(12小时制,01 - 12) 9 %j 一年中的第几天(001 - 366) 10 %m 月份(01 - 12) 11 %M 分钟数(00 - 59) 12 %p 本地am或者pm的相应符 13 %S 秒(01 - 61) 14 %U 一年中的星期数。(00 - 53星期天是一个星期的开始。)第一个星期天之前的所有天数都放在第0周。 15 %w 一个星期中的第几天(0 - 6,0是星期天) 16 %W 和%U基本相同,不同的是%W以星期一为一个星期的开始。 17 %x 本地相应日期 18 %X 本地相应时间 19 %y 去掉世纪的年份(00 - 99) 20 %Y 完整的年份 21 %Z 时区的名字(如果不存在为空字符) 22 %% ‘%’字符
3.random模块
1 #!/usr/bin/env python 2 #_*_encoding: utf-8_*_ 3 import random 4 print (random.random()) #0.6445010863311293 5 #random.random()用于生成一个0到1的随机符点数: 0 <= n < 1.0 6 print (random.randint(1,7)) #4 7 #random.randint()的函数原型为:random.randint(a, b),用于生成一个指定范围内的整数。 8 # 其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b 9 print (random.randrange(1,10)) #5 10 #random.randrange的函数原型为:random.randrange([start], stop[, step]), 11 # 从指定范围内,按指定基数递增的集合中 获取一个随机数。如:random.randrange(10, 100, 2), 12 # 结果相当于从[10, 12, 14, 16, ... 96, 98]序列中获取一个随机数。 13 # random.randrange(10, 100, 2)在结果上与 random.choice(range(10, 100, 2) 等效。 14 print(random.choice('liukuni')) #i 15 #random.choice从序列中获取一个随机元素。 16 # 其函数原型为:random.choice(sequence)。参数sequence表示一个有序类型。 17 # 这里要说明一下:sequence在python不是一种特定的类型,而是泛指一系列的类型。 18 # list, tuple, 字符串都属于sequence。有关sequence可以查看python手册数据模型这一章。 19 # 下面是使用choice的一些例子: 20 print(random.choice("学习Python"))#学 21 print(random.choice(["JGood","is","a","handsome","boy"])) #List 22 print(random.choice(("Tuple","List","Dict"))) #List 23 print(random.sample([1,2,3,4,5],3)) #[1, 2, 5] 24 #random.sample的函数原型为:random.sample(sequence, k),从指定序列中随机获取指定长度的片断。sample函数不会修改原有序列。
实际应用:
1 #!/usr/bin/env python 2 # encoding: utf-8 3 import random 4 import string 5 #随机整数: 6 print( random.randint(0,99)) #70 7 8 #随机选取0到100间的偶数: 9 print(random.randrange(0, 101, 2)) #4 10 11 #随机浮点数: 12 print( random.random()) #0.2746445568079129 13 print(random.uniform(1, 10)) #9.887001463194844 14 15 #随机字符: 16 print(random.choice('abcdefg&#%^*f')) #f 17 18 #多个字符中选取特定数量的字符: 19 print(random.sample('abcdefghij',3)) #['f', 'h', 'd'] 20 21 #随机选取字符串: 22 print( random.choice ( ['apple', 'pear', 'peach', 'orange', 'lemon'] )) #apple 23 #洗牌# 24 items = [1,2,3,4,5,6,7] 25 print(items) #[1, 2, 3, 4, 5, 6, 7] 26 random.shuffle(items) 27 print(items) #[1, 4, 7, 2, 5, 3, 6]
随机生成验证码:
1 # _*_ coding:utf-8 _*_ 2 __author__ = "ZingP" 3 4 import random 5 security_code = '' 6 for i in range(0,5): 7 j = random.randrange(0,5) 8 if i == j: 9 ptm = random.randint(0,9) 10 else: 11 ptm = chr(random.randint(97,122)) 12 security_code += str(ptm) 13 print('security code:',security_code )
4.os
提供对操作系统进行调用的接口:
os.path.basename() 去掉目录路径, 返回文件名 os.path.dirname() 去掉文件名, 返回目录路径 os.path.join() 将分离的各部分组合成一个路径名 os.path.split() 返回目录和文件的元组 (dir, file)【给的是目录则会返回最后一个目录名和前面的路径】 os.path.splitdrive() 返回盘符和路径的元组 (drivename, pathname) os.path.splitext() 返回文件名和扩展名的元组(filename, extension) os.path.abspath() 获得绝对路径(不太好使) os.path.normpath() 规范path字符串形式 os.path.getatime() 返回最近访问时间的时间戳 os.path.getctime() 返回文件创建时间的时间戳 os.path.getmtime() 返回最近文件修改时间的时间戳 os.path.getsize() 返回文件或目录大小(以字节为单位) os.path.walk() 搜索目录下的所有文件 os.path.exists() 指定路径(文件或目录)是否存在 os.path.isabs() 指定路径是否为绝对路径 os.path.isdir() 指定路径是否存在且为一个目录 os.path.isfile() 指定路径是否存在且为一个文件 os.path.islink() 指定路径是否存在且为一个符号链接 os.path.ismount() 指定路径是否存在且为一个挂载点 os.path.samefile() 两个路径名是否指向同个文件 os.environ 获取系统环境变量 os.linesep 获取本系统的换行符 os.sep 获取路径分割符 os.pathsep 路径与路径之间的分割符字符串 os.curdir 当前工作目录的字符串名称(.) os.pardir (当前工作目录的)父目录字符串名称(..) os.name 输出字符串指示当前系统平台'nt'->win;'posix'->Linux os.rename(old, new) 重命名 os.remove() 删除文件 os.listdir() 列出目录下的文件(目录也是文件): os.getcwd() 获取当前工作目录: os.chdir() 改变工作目录: os.makedirs() 创建多级目录 os.mkdir() 创建单个目录 os.removedirs() 删除所给路径最后一个目录下所有空目录。 os.rmdir("test") 删除单个目录 os.stat(file) 获取文件属性 os.chmod(file) 修改文件权限与时间戳 os.system("dir") 执行操作系统命令 os.exec()/os.execvp()启动新进程 os.spawnv() 在后台执行程序 os.exit()/os._exit() 终止当前进程 os.ismount() 是否挂载
5.sys
常用函数
sys.argv # 命令行参数List,python t.py 1 sys.arsv[0]是t.py sys.exit(n) # 退出程序,正常退出时exit(0) sys.version # 获取Python解释程序的版本信息 sys.maxint # 最大的Int值 sys.path # 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform # 返回操作系统平台名称 sys.getrecursionlimit() # 获取最大递归层数 sys.setrecursionlimit(2000) # 设置最大递归层数为2000 sys.stdout.write('please:') val = sys.stdin.readline()[:-1] sys.modules # 已加载模块的字典 sys.version # 版本信息 sys.version_info # 版本信息的命名元组 sys.copyright # 获取python版权相关信息 sys.builtin_module_names # 获得python内建模块名称(字符串元组)
示例:
>>> import sys >>> sys.getrecursionlimit() 1000 >>> sys.setrecursionlimit(2000) >>> sys.getrecursionlimit() 2000
6.shutil模块
更多:http://www.cnblogs.com/wupeiqi/articles/4963027.html
7.json & pickle模块
用于序列化的两个模块
-
json,用于字符串 和 python数据类型间进行转换
-
pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
1 import pickle 2 a = {'a':'bc','c':'hello','d':123,'e':'world'} 3 f = open('a.pkl','wb') 4 pickle.dump(a,f)#如果跨语言平台使用json 5 f.close() 6 ''' 7 >>> a = {'a':'bc','c':'hello','d':123,'e':'world'} 8 >>> import json 9 >>> json.dumps(a) 10 '{"a": "bc", "d": 123, "e": "world", "c": "hello"}' 11 >>> b = json.dumps(a) 12 >>> json.loads(b) 13 {'a': 'bc', 'd': 123, 'e': 'world', 'c': 'hello'} 14 '''
1 import pickle 2 f = open('a.pkl','rb') 3 acc = pickle.load(f) 4 print(acc)
8.shelve
9.xml处理
10.yaml处理
11.configparser
12.hashlib
用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
1 #! /usr/bin/env python3 2 3 import hashlib 4 5 # ######## md5 ######## 6 hash = hashlib.md5() 7 hash.update(b'love you baby..') 8 print(hash.hexdigest()) 9 10 # ######## sha1 ######## 11 hash = hashlib.sha1() 12 hash.update(b'love you baby..') 13 print(hash.hexdigest()) 14 15 # ######## sha256 ######## 16 hash = hashlib.sha256() 17 hash.update(b'love you baby..') 18 print(hash.hexdigest()) 19 20 # ######## sha384 ######## 21 hash = hashlib.sha384() 22 hash.update(b'love you baby..') 23 print(hash.hexdigest()) 24 25 # ######## sha512 ######## 26 hash = hashlib.sha512() 27 hash.update(b'love you baby..') 28 print(hash.hexdigest())
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
1 #! /usr/bin/env python3 2 3 import hashlib 4 5 # ######## md5 ######## 6 hash = hashlib.md5(b'898oaFs09f') 7 hash.update(b'love you baby...') 8 print(hash.hexdigest())
还不够吊?python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
1 import hmac 2 h = hmac.new(b'zingp') 3 h.update(b'hello') 4 print(h.hexdigest())
13.subprocess
可以执行shell命令的相关模块和函数有:
- os.system
- os.spawn*
- os.popen* --废弃
- popen2.* --废弃
- commands.* --废弃,3.x中被移除
以上执行shell命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了更丰富的功能。
call
执行命令,返回状态码
ret = subprocess.call(["ls", "-l"], shell=False) ret = subprocess.call("ls -l", shell=True)
shell = True ,允许 shell 命令是字符串形式
check_call
执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
1 subprocess.check_call(["ls", "-l"]) 2 subprocess.check_call("exit 1", shell=True)
check_output
执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
1 subprocess.check_output(["echo", "Hello World!"]) 2 subprocess.check_output("exit 1", shell=True)
调用subprocess.run(...)是推荐的常用方法,在大多数情况下能满足需求。
1 >>> subprocess.run(["ls", "-l"]) # doesn't capture output 2 CompletedProcess(args=['ls', '-l'], returncode=0) 3 4 >>> subprocess.run("exit 1", shell=True, check=True) 5 Traceback (most recent call last): 6 ... 7 subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 8 9 >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) 10 CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, 11 stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null ')
subprocess.Popen(...)
用于执行复杂的系统命令
参数:
- args:shell命令,可以是字符串或者序列类型(如:list,元组)
- bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
- stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
- preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
- close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。 - shell:同上
- cwd:用于设置子进程的当前目录
- env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
- universal_newlines:不同系统的换行符不同,True -> 同意使用
- startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
1 import subprocess 2 ret1 = subprocess.Popen(["mkdir","t1"]) 3 ret2 = subprocess.Popen("mkdir t2", shell=True)
终端输入的命令分为两种:
- 输入即可得到输出,如:ifconfig
- 输入进行某环境,依赖再输入,如:python
1 import subprocess 2 3 obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
示例:
1 import subprocess 2 3 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 4 obj.stdin.write('print 1 ') 5 obj.stdin.write('print 2 ') 6 obj.stdin.write('print 3 ') 7 obj.stdin.write('print 4 ') 8 obj.stdin.close() 9 10 cmd_out = obj.stdout.read() 11 obj.stdout.close() 12 cmd_error = obj.stderr.read() 13 obj.stderr.close() 14 15 print cmd_out 16 print cmd_error
1 import subprocess 2 3 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 4 obj.stdin.write('print 1 ') 5 obj.stdin.write('print 2 ') 6 obj.stdin.write('print 3 ') 7 obj.stdin.write('print 4 ') 8 9 out_error_list = obj.communicate() 10 print out_error_list
1 import subprocess 2 3 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 4 out_error_list = obj.communicate('print "hello"') 5 print out_error_list
14.logging模块
用于便捷记录日志且线程安全的模块
1 #! /usr/bin/env python3 2 import logging 3 4 logging.basicConfig(filename='mylog.log', 5 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', 6 datefmt='%Y-%m-%d %H:%M:%S %p', 7 level=10) 8 # level设置值就是当出现这个情况或比这个值更严重的情况才记录日志 9 logging.debug('1111') 10 logging.info('2222') 11 logging.warning('3333') 12 logging.error('4444') 13 logging.critical('5555') 14 logging.log(10, 'logqqq')
运行结果,mylog.log文件中的内容:
1 2016-11-22 10:52:37 AM - root - DEBUG -test1: 1111 2 2016-11-22 10:52:37 AM - root - INFO -test1: 2222 3 2016-11-22 10:52:37 AM - root - WARNING -test1: 3333 4 2016-11-22 10:52:37 AM - root - ERROR -test1: 4444 5 2016-11-22 10:52:37 AM - root - CRITICAL -test1: 5555 6 2016-11-22 10:52:37 AM - root - DEBUG -test1: logqqq
日志的几个等级:
1 CRITICAL = 50 2 FATAL = CRITICAL 3 ERROR = 40 4 WARNING = 30 5 WARN = WARNING 6 INFO = 20 7 DEBUG = 10 8 NOTSET = 0
日志的格式,可以配置下面的属性:
15.re正则表达式
常用正则符号
1 '.' 默认匹配除 之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 2 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a"," abc eee",flags=re.MULTILINE) 3 '$' 匹配字符结尾,或e.search("foo$","bfoo sdfsf",flags=re.MULTILINE).group()也可以 4 '*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a'] 5 '+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb'] 6 '?' 匹配前一个字符1次或0次 7 '{m}' 匹配前一个字符m次 8 '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] 9 '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC' 10 '(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c 11 12 13 'A' 只从字符开头匹配,re.search("Aabc","alexabc") 是匹配不到的 14 '' 匹配字符结尾,同$ 15 'd' 匹配数字0-9 16 'D' 匹配非数字 17 'w' 匹配[A-Za-z0-9] 18 'W' 匹配非[A-Za-z0-9] 19 's' 匹配空白字符、 、 、 , re.search("s+","ab c1 3").group() 结果 ' ' 20 21 '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
示例:
# _*_ coding:utf-8 _*_ __author__ = "ZingP" import re a = 'abc1234(hh+12hhdd][wdbrgwnq' # '.'默认匹配除 之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 b = re.search('.', a) print(b.group()) # result:a c = re.search('.', ' bcd', flags=re.DOTALL) print(c) # result:<_sre.SRE_Match object; span=(0, 1), match=' '> # 这里print(c.group()) 什么也打印不了, 不能用group??? # '^'匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a"," abc eee",flags=re.MULTILINE) print(re.search('^b', 'bard').group()) # result: b # '$'匹配字符结尾,或e.search("foo$","bfoo sdfsf",flags=re.MULTILINE).group()也可以 print(re.search('2$', 'ggcba12').group()) # result:2 # 匹配*号前的字符0次或多次 print(re.search('ac*', 'accqwiuewac457ab').group()) # result:acc print(re.findall('ac*', 'accqwiuewac457ab')) # result:['acc', 'ac', 'a'] # '+' 匹配前一个字符1次或多次 print(re.findall("ab+", "ab+cd+abb+bba")) # result:['ab', 'abb'] # '?' 匹配前一个字符1次或0次 print(re.findall('ab?', 'cdab90oladh')) # result:['ab', 'a'] # '{m}' 匹配前一个字符m次 print(re.findall('ab{3}', 'cdab90olabbbbcdh')) # result:['abbb'] # '{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb'] print(re.findall('ab{1,3}', 'cdab90olabbbbcdh')) # ['ab', 'abbb'] # '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC' print(re.findall("abc|ABC","ABCB23abcCD")) # ['ABC', 'abc'] # '(...)' 分组匹配, 结果 abcabca456c print(re.search("(abc){2}a(123|456)c", "abcabca456c").group()) # abcabca456c # 关于反斜杠 print(re.search(r'\', 'dc')) # <_sre.SRE_Match object; span=(0, 1), match='\'> print(re.findall(r'\', 'ssdc')) # ['\', '\']??? print(re.search('\\', 'dc').group()) # print(re.search("(?P<id>[0-9]+)(?P<name>[A-Za-z]+)", "as123alex+++").groupdict()) # {'name': 'alex', 'id': '123'} # re.sub匹配到的替换 count为替换次数 print(re.sub('[0-9]+', '|', 'abc12df34hh56n', count=2)) # abc|df|hh56n print(re.sub('[0-9]+', '|', 'abc12df34hh56n', count=3)) # abc|df|hh|n print(re.findall("[0-9]{1,3}","aa1xxx2y3456")) # ['1', '2', '345', '6'] print(re.findall("[0-9]{1,3}","aa1xxx2y3456")) # ['1', '2', '345', '6']
语法:
1 re.match 从头开始匹配 2 re.search 匹配包含 3 re.findall 把所有匹配到的字符放到以列表中的元素返回 4 re.splitall 以匹配到的字符当做列表分隔符 5 re.sub 匹配字符并替换
了解几个匹配模式:
1 re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同) 2 M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图) 3 S(DOTALL): 点任意匹配模式,改变'.'的行为