day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)

时间:2022-12-15 20:15:37

re模块

一:什么是正则?

 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

生活中处处都是正则:

    比如我们描述:4条腿

      你可能会想到的是四条腿的动物或者桌子,椅子等

    继续描述:4条腿,活的

          就只剩下四条腿的动物这一类了

二:常用匹配模式(元字符)

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 # =================================匹配模式=================================
 2 #一对一的匹配
 3 # 'hello'.replace(old,new)
 4 # 'hello'.find('pattern')
 5 
 6 #正则匹配
 7 import re
 8 #\w与\W
 9 print(re.findall('\w','hello egon 123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
10 print(re.findall('\W','hello egon 123')) #[' ', ' ']
11 
12 #\s与\S
13 print(re.findall('\s','hello  egon  123')) #[' ', ' ', ' ', ' ']
14 print(re.findall('\S','hello  egon  123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
15 
16 #\n \t都是空,都可以被\s匹配
17 print(re.findall('\s','hello \n egon \t 123')) #[' ', '\n', ' ', ' ', '\t', ' ']
18 
19 #\n与\t
20 print(re.findall(r'\n','hello egon \n123')) #['\n']
21 print(re.findall(r'\t','hello egon\t123')) #['\n']
22 
23 #\d与\D
24 print(re.findall('\d','hello egon 123')) #['1', '2', '3']
25 print(re.findall('\D','hello egon 123')) #['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']
26 
27 #\A与\Z
28 print(re.findall('\Ahe','hello egon 123')) #['he'],\A==>^
29 print(re.findall('123\Z','hello egon 123')) #['he'],\Z==>$
30 
31 #^与$
32 print(re.findall('^h','hello egon 123')) #['h']
33 print(re.findall('3$','hello egon 123')) #['3']
34 
35 # 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
36 #.
37 print(re.findall('a.b','a1b')) #['a1b']
38 print(re.findall('a.b','a1b a*b a b aaab')) #['a1b', 'a*b', 'a b', 'aab']
39 print(re.findall('a.b','a\nb')) #[]
40 print(re.findall('a.b','a\nb',re.S)) #['a\nb']
41 print(re.findall('a.b','a\nb',re.DOTALL)) #['a\nb']同上一条意思一样
42 
43 #*
44 print(re.findall('ab*','bbbbbbb')) #[]
45 print(re.findall('ab*','a')) #['a']
46 print(re.findall('ab*','abbbb')) #['abbbb']
47 
48 #?
49 print(re.findall('ab?','a')) #['a']
50 print(re.findall('ab?','abbb')) #['ab']
51 #匹配所有包含小数在内的数字
52 print(re.findall('\d+\.?\d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3']
53 
54 #.*默认为贪婪匹配
55 print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b']
56 
57 #.*?为非贪婪匹配:推荐使用
58 print(re.findall('a.*?b','a1b22222222b')) #['a1b']
59 
60 #+
61 print(re.findall('ab+','a')) #[]
62 print(re.findall('ab+','abbb')) #['abbb']
63 
64 #{n,m}
65 print(re.findall('ab{2}','abbb')) #['abb']
66 print(re.findall('ab{2,4}','abbb')) #['abb']
67 print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+'
68 print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*'
69 
70 #[]
71 print(re.findall('a[1*-]b','a1b a*b a-b')) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾
72 print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']
73 print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']
74 print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #[]内的^代表的意思是取反,所以结果为['a=b']
75 print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) #[]内的^代表的意思是取反,所以结果为['a=b']
76 
77 #\# print(re.findall('a\\c','a\c')) #对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常
78 print(re.findall(r'a\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
79 print(re.findall('a\\\\c','a\c')) #同上面的意思一样,和上面的结果一样都是['a\\c']
80 
81 #():分组
82 print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']
83 print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的ab
84 print(re.findall('(?:ab)+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容
85 print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击</a>'))#['http://www.baidu.com']
86 print(re.findall('href="(?:.*?)"','<a href="http://www.baidu.com">点击</a>'))#['href="http://www.baidu.com"']
87 
88 #|
89 print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))
re模块元字符使用实例
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 # str1 = '1abc a1 c aac aAc\n \taBc asd aaaaac a-c a/c a *c a+c abasd = a1c a2c'
 2 import  re
 3 # print(re.findall('\w',str1)) #\w---匹配字母数字及下划线
 4 # print(re.findall('\W',str1)) #\w---匹配非字母数字及下划线 \n \t
 5 # print(re.findall('\s',str1)) #匹配任意空白字符\n\t\r\f
 6 # print(re.findall('\S',str1)) #匹配非空白字符
 7 # print(re.findall('\d',str1)) #匹配数字等价0-9
 8 # print(re.findall('\D',str1)) #匹配任意非数字0-9
 9 # print(re.findall('\Aac',str1)) #匹配字母开始
10 # print(re.findall('\\n\Z',str1)) #匹配字母结束,只匹配到换行前的结束字符串
11 # print(re.findall('\G',str1)) #匹配字母结束,只匹配到换行前的结束字符串
12 # print(re.findall('\n',str1)) #匹配换行符
13 # print(re.findall('\t',str1)) #匹配换行符
14 # print(re.findall('^1abc',str1)) #匹配以什么开头
15 # print(re.findall('c$',str1))  #匹配以什么结尾
16 str1 = '1abbb a1 a\nbc aac aAc\n \taBc asd aaaaac a-c a/c a *c a+c abasd = a1c a2c'
17 # print(re.findall('a.b',str1))#匹配中间是任意字符除了换行符
18 # print(re.findall('a.b',str1,re.S))#匹配中间是任意字符包含换行符
19 # print(re.findall('a.b',str1,re.DOTALL))#匹配中间是任意字符包含换行符
20 # print(re.findall('ab*',str1)) #匹配0个或多个表达式
21 # print(re.findall('ab+',str1)) #匹配1个或多个表达式
22 # print(re.findall('ab?',str1)) #匹配0个或1个表达式
23 # print(re.findall('ab?a',str1)) #匹配0个或1个表达式指代找b
24 # print(re.findall('ab{2}','abbb aabxbaa')) #表示1个a2个b
25 # print(re.findall('a[1*-]b','a1b  a\nb a*b a-b')) #['a1b', 'a*b', 'a-b']
26 # print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^表示取反
27 # print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #['a1b']
28 # print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #['aeb']
29 # print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb'))#['aeb', 'aEb']
30 # print(re.findall(r'a\\c','a\c'))
31 # print(re.findall('(ab)+123','ababab123'))
32 # print(re.findall('(?:ab)+123','xxxaab123')) #['ab123']
33 # print(re.findall('(?:ab)+123','12abab123'))#['abab123']如果有相同的ab连接在一起就一起显示
34 # print(re.findall('compan(?:ies|y)','Too many companies have gone bankrupt, and the next one is my company'))
35 # print(re.findall('href="(.*?)"','<p>段落</p><a href="https://www.sb.com">点我啊</a><h1>标题</h1><a href="https://www.sb.com">点我啊</a>'))
36 # print(re.findall('a|b','ab123abasdfaf'))
37 # print(re.split('ab','abcd')) #['', 'cd']
38 # print(re.split('[ab]','abcd')) #['', '', 'cd'] #如果是列表按照索引取
39 # print('===>',re.sub('a','A','alex make love')) #===> Alex mAke love,不指定n,默认替换所有
40 # print('===>',re.sub('a','A','alex make love',1)) #===> Alex make love
41 
42 # obj=re.compile('\d{3}') #查找3个数字还要连续的
43 # # print(obj.search('abc123eee1e').group()) #12
44 # print(obj.findall('abc123eeee')) #['12'],重用了obj
45 
46 
47 # print(re.findall('a,b|c','ac,a,b,accc'))
48 # print(re.findall('ab?','a'))
re模块实际练习
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import re
 2 #1
 3 print(re.findall('e','alex make love') )   #['e', 'e', 'e'],返回所有满足匹配条件的结果,放在列表里
 4 #2
 5 print(re.search('e','alex make love').group()) #e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
 6 
 7 #3
 8 print(re.match('e','alex make love'))    #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match
 9 
10 #4
11 print(re.split('[ab]','abcd'))     #['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割
12 
13 #5
14 print('===>',re.sub('a','A','alex make love')) #===> Alex mAke love,不指定n,默认替换所有
15 print('===>',re.sub('a','A','alex make love',1)) #===> Alex make love
16 print('===>',re.sub('a','A','alex make love',2)) #===> Alex mAke love
17 print('===>',re.sub('^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$',r'\5\2\3\4\1','alex make love')) #===> love make alex
18 
19 print('===>',re.subn('a','A','alex make love')) #===> ('Alex mAke love', 2),结果带有总共替换的个数
20 
21 
22 #6
23 obj=re.compile('\d{2}')
24 
25 print(obj.search('abc123eeee').group()) #12
26 print(obj.findall('abc123eeee')) #['12'],重用了obj
re模块提供的方法介绍
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
1 import re
2 print(re.findall("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")) #['h1']
3 print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>").group()) #<h1>hello</h1>
4 print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>").groupdict()) #<h1>hello</h1>
5 
6 print(re.search(r"<(\w+)>\w+</(\w+)>","<h1>hello</h1>").group())
7 print(re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>").group())
补充一
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
1 #计算器作业参考:http://www.cnblogs.com/wupeiqi/articles/4949995.html
2 expression='1-2*((60+2*(-3-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
3 
4 content=re.search('\(([\-\+\*\/]*\d+\.?\d*)+\)',expression).group() #(-3-40.0/5)
补充二
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
1 #为何同样的表达式search与findall却有不同结果:
2 print(re.search('\(([\+\-\*\/]*\d+\.?\d*)+\)',"1-12*(60+(-40.35/5)-(-4*3))").group()) #(-40.35/5)
3 print(re.findall('\(([\+\-\*\/]*\d+\.?\d*)+\)',"1-12*(60+(-40.35/5)-(-4*3))")) #['/5', '*3']
4 
5 #看这个例子:(\d)+相当于(\d)(\d)(\d)(\d)...,是一系列分组
6 print(re.search('(\d)+','123').group()) #group的作用是将所有组拼接到一起显示出来
7 print(re.findall('(\d)+','123')) #findall结果是组内的结果,且是最后一个组的结果
serach与findall
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 #_*_coding:utf-8_*_
 2 __author__ = 'Linhaifeng'
 3 #在线调试工具:tool.oschina.net/regex/#
 4 import re
 5 
 6 s='''
 7 http://www.baidu.com
 8 egon@oldboyedu.com
 9 你好
10 010-3141
11 '''
12 
13 #最常规匹配
14 # content='Hello 123 456 World_This is a Regex Demo'
15 # res=re.match('Hello\s\d\d\d\s\d{3}\s\w{10}.*Demo',content)
16 # print(res)
17 # print(res.group())
18 # print(res.span())
19 
20 #泛匹配
21 # content='Hello 123 456 World_This is a Regex Demo'
22 # res=re.match('^Hello.*Demo',content)
23 # print(res.group())
24 
25 
26 #匹配目标,获得指定数据
27 
28 # content='Hello 123 456 World_This is a Regex Demo'
29 # res=re.match('^Hello\s(\d+)\s(\d+)\s.*Demo',content)
30 # print(res.group()) #取所有匹配的内容
31 # print(res.group(1)) #取匹配的第一个括号内的内容
32 # print(res.group(2)) #去陪陪的第二个括号内的内容
33 
34 
35 
36 #贪婪匹配:.*代表匹配尽可能多的字符
37 # import re
38 # content='Hello 123 456 World_This is a Regex Demo'
39 #
40 # res=re.match('^He.*(\d+).*Demo$',content)
41 # print(res.group(1)) #只打印6,因为.*会尽可能多的匹配,然后后面跟至少一个数字
42 
43 
44 #非贪婪匹配:?匹配尽可能少的字符
45 # import re
46 # content='Hello 123 456 World_This is a Regex Demo'
47 #
48 # res=re.match('^He.*?(\d+).*Demo$',content)
49 # print(res.group(1)) #只打印6,因为.*会尽可能多的匹配,然后后面跟至少一个数字
50 
51 
52 #匹配模式:.不能匹配换行符
53 content='''Hello 123456 World_This
54 is a Regex Demo
55 '''
56 # res=re.match('He.*?(\d+).*?Demo$',content)
57 # print(res) #输出None
58 
59 # res=re.match('He.*?(\d+).*?Demo$',content,re.S) #re.S让.可以匹配换行符
60 # print(res)
61 # print(res.group(1))
62 
63 
64 #转义:\
65 
66 # content='price is $5.00'
67 # res=re.match('price is $5.00',content)
68 # print(res)
69 #
70 # res=re.match('price is \$5\.00',content)
71 # print(res)
72 
73 
74 #总结:尽量精简,详细的如下
75     # 尽量使用泛匹配模式.*
76     # 尽量使用非贪婪模式:.*?
77     # 使用括号得到匹配目标:用group(n)去取得结果
78     # 有换行符就用re.S:修改模式
View Code

sys模块

1 1 sys.argv           命令行参数List,第一个元素是程序本身路径
2 2 sys.exit(n)        退出程序,正常退出时exit(0)
3 3 sys.version        获取Python解释程序的版本信息
4 4 sys.maxint         最大的Int值
5 5 sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
6 6 sys.platform       返回操作系统平台名称

suprocess模块

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1  1 import  subprocess
 2  2 
 3  3 '''
 4  4 sh-3.2# ls /Users/egon/Desktop |grep txt$
 5  5 mysql.txt
 6  6 tt.txt
 7  7 事物.txt
 8  8 '''
 9  9 
10 10 res1=subprocess.Popen('ls /Users/jieli/Desktop',shell=True,stdout=subprocess.PIPE)
11 11 res=subprocess.Popen('grep txt$',shell=True,stdin=res1.stdout,
12 12                  stdout=subprocess.PIPE)
13 13 
14 14 print(res.stdout.read().decode('utf-8'))
15 15 
16 16 
17 17 #等同于上面,但是上面的优势在于,一个数据流可以和另外一个数据流交互,可以通过爬虫得到结果然后交给grep
18 18 res1=subprocess.Popen('ls /Users/jieli/Desktop |grep txt$',shell=True,stdout=subprocess.PIPE)
19 19 print(res1.stdout.read().decode('utf-8'))
20 20 
21 21 
22 22 #windows下:
23 23 # dir | findstr 'test*'
24 24 # dir | findstr 'txt$'
25 25 import subprocess
26 26 res1=subprocess.Popen(r'dir C:\Users\Administrator\PycharmProjects\test\函数备课',shell=True,stdout=subprocess.PIPE)
27 27 res=subprocess.Popen('findstr test*',shell=True,stdin=res1.stdout,
28 28                  stdout=subprocess.PIPE)
29 29 
30 30 print(res.stdout.read().decode('gbk')) #subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码
View Code

hashlib模块

# 1、什么叫hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值
# 2、hash值的特点是:
#2.1 只要传入的内容一样,得到的hash值必然一样=====>要用明文传输密码文件完整性校验
#2.2 不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码
#2.3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的

 hash算法就像一座工厂,工厂接收你送来的原材料(可以用m.update()为工厂运送原材料),经过加工返回的产品就是hash值

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)import day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import hashlib
 2  
 3 m=hashlib.md5()# m=hashlib.sha256()
 4  
 5 m.update('hello'.encode('utf8'))
 6 print(m.hexdigest())  #5d41402abc4b2a76b9719d911017c592
 7  
 8 m.update('alvin'.encode('utf8'))
 9  
10 print(m.hexdigest())  #92a7e713c30abbb0319fa07da2a5c4af
11  
12 m2=hashlib.md5()
13 m2.update('helloalvin'.encode('utf8'))
14 print(m2.hexdigest()) #92a7e713c30abbb0319fa07da2a5c4af
15 
16 '''
17 注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
18 但是update多次为校验大文件提供了可能。
19 '''
导入hash用法
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
 2 
 3 复制代码
 4 1 import hashlib
 5 2  
 6 3 # ######## 256 ########
 7 4  
 8 5 hash = hashlib.sha256('898oaFs09f'.encode('utf8'))
 9 6 hash.update('alvin'.encode('utf8'))
10 7 print (hash.hexdigest())#e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7
hash可以通过key来做加密
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import hashlib
 2 passwds=[
 3     'alex3714',
 4     'alex1313',
 5     'alex94139413',
 6     'alex123456',
 7     '123456alex',
 8     'a123lex',
 9     ]
10 def make_passwd_dic(passwds):
11     dic={}
12     for passwd in passwds:
13         m=hashlib.md5()
14         m.update(passwd.encode('utf-8'))
15         dic[passwd]=m.hexdigest()
16     return dic
17 
18 def break_code(cryptograph,passwd_dic):
19     for k,v in passwd_dic.items():
20         if v == cryptograph:
21             print('密码是===>\033[46m%s\033[0m' %k)
22 
23 cryptograph='aee949757a2e698417463d47acac93df'
24 break_code(cryptograph,make_passwd_dic(passwds))
密码库撞库解密

 python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密:

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
1 1 import hmac
2 2 h = hmac.new('alvin'.encode('utf8'))
3 3 h.update('hello'.encode('utf8'))
4 4 print (h.hexdigest())#320df9832eab4c038b6c1d7ed73a5940
View Code
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 #要想保证hmac最终结果一致,必须保证:
 2 #1:hmac.new括号内指定的初始key一样
 3 #2:无论update多少次,校验的内容累加到一起是一样的内容
 4 
 5 import hmac
 6 
 7 h1=hmac.new(b'egon')
 8 h1.update(b'hello')
 9 h1.update(b'world')
10 print(h1.hexdigest())
11 
12 h2=hmac.new(b'egon')
13 h2.update(b'helloworld')
14 print(h2.hexdigest())
15 
16 h3=hmac.new(b'egonhelloworld')
17 print(h3.hexdigest())
18 
19 '''
20 f1bf38d054691688f89dcd34ac3c27f2
21 f1bf38d054691688f89dcd34ac3c27f2
22 bcca84edd9eeb86f30539922b28f3981
23 '''
注意的点

shutil模块

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
#高级的 文件、文件夹、压缩包 处理模块shutil.copyfileobj(fsrc, fdst[, length])将文件内容拷贝到另一个文件中
import shutil
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
 #1
shutil.copyfile(src, dst)
拷贝文件
shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
#2
shutil.copymode(src, dst)仅拷贝权限。内容、组、用户均不变
shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
#3
shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
#4
shutil.copy(src, dst)拷贝文件和权限
import shutil
shutil.copy('f1.log', 'f2.log')
#5
shutil.copy2(src, dst)拷贝文件和状态信息
import shutil
shutil.copy2('f1.log', 'f2.log')
#6
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
#7
import shutil  
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除 
shutil一些常用操作
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
1 import shutil
2 
3 shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
4 
5 '''
6 通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
拷贝软连接
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 shutil.rmtree(path[, ignore_errors[, onerror]])
 2 递归的去删除文件
 3 
 4 1 import shutil
 5 2  
 6 3 shutil.rmtree('folder1')
 7  
 8 
 9 shutil.move(src, dst)
10 递归的去移动文件,它类似mv命令,其实就是重命名。
11 
12 1 import shutil
13 2  
14 3 shutil.move('folder1', 'folder3')
删除文件
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 shutil.make_archive(base_name, format,...)
 2 
 3 创建压缩包并返回文件路径,例如:zip、tar
 4 
 5 创建压缩包并返回文件路径,例如:zip、tar
 6 
 7 base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
 8 如 data_bak                       =>保存至当前路径
 9 如:/tmp/data_bak =>保存至/tmp/
10 format:    压缩包种类,“zip”, “tar”, “bztar”,“gztar”
11 root_dir:    要压缩的文件夹路径(默认当前目录)
12 owner:    用户,默认当前用户
13 group:    组,默认当前组
14 logger:    用于记录日志,通常是logging.Logger对象
15 
16 #将 /data 下的文件打包放置当前程序目录
17 import shutil
18 ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
19   
20   
21 #将 /data下的文件打包放置 /tmp/目录
22 import shutil
23 ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
View Code
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import zipfile
 2 
 3 # 压缩
 4 z = zipfile.ZipFile('laxi.zip', 'w')
 5 z.write('a.log')
 6 z.write('data.data')
 7 z.close()
 8 
 9 # 解压
10 z = zipfile.ZipFile('laxi.zip', 'r')
11 z.extractall(path='.')
12 z.close()
13 
14 zipfile压缩解压缩
zipfile压缩
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import tarfile
 2 
 3 # 压缩
 4 >>> t=tarfile.open('/tmp/egon.tar','w')
 5 >>> t.add('/test1/a.py',arcname='a.bak')
 6 >>> t.add('/test1/b.py',arcname='b.bak')
 7 >>> t.close()
 8 
 9 
10 # 解压
11 >>> t=tarfile.open('/tmp/egon.tar','r')
12 >>> t.extractall('/egon')
13 >>> t.close()
14 
15 tarfile压缩解压缩
tarfile解压缩

 xml模块

xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

xml的格式如下,就是通过<>节点来区别数据结构的:

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 <?xml version="1.0"?>
 2 <data>
 3     <country name="Liechtenstein">
 4         <rank updated="yes">2</rank>
 5         <year>2008</year>
 6         <gdppc>141100</gdppc>
 7         <neighbor name="Austria" direction="E"/>
 8         <neighbor name="Switzerland" direction="W"/>
 9     </country>
10     <country name="Singapore">
11         <rank updated="yes">5</rank>
12         <year>2011</year>
13         <gdppc>59900</gdppc>
14         <neighbor name="Malaysia" direction="N"/>
15     </country>
16     <country name="Panama">
17         <rank updated="yes">69</rank>
18         <year>2011</year>
19         <gdppc>13600</gdppc>
20         <neighbor name="Costa Rica" direction="W"/>
21         <neighbor name="Colombia" direction="E"/>
22     </country>
23 </data>
24 
25 xml数据
xml数据

xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

print(root.iter('year')) #全文搜索
print(root.find('country')) #在root的子节点找,只找一个
print(root.findall('country')) #在root的子节点找,找所有
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import xml.etree.ElementTree as ET
 2  
 3 tree = ET.parse("xmltest.xml")
 4 root = tree.getroot()
 5 print(root.tag)
 6  
 7 #遍历xml文档
 8 for child in root:
 9     print('========>',child.tag,child.attrib,child.attrib['name'])
10     for i in child:
11         print(i.tag,i.attrib,i.text)
12  
13 #只遍历year 节点
14 for node in root.iter('year'):
15     print(node.tag,node.text)
16 #---------------------------------------
17 
18 import xml.etree.ElementTree as ET
19  
20 tree = ET.parse("xmltest.xml")
21 root = tree.getroot()
22  
23 #修改
24 for node in root.iter('year'):
25     new_year=int(node.text)+1
26     node.text=str(new_year)
27     node.set('updated','yes')
28     node.set('version','1.0')
29 tree.write('test.xml')
30  
31  
32 #删除node
33 for country in root.findall('country'):
34    rank = int(country.find('rank').text)
35    if rank > 50:
36      root.remove(country)
37  
38 tree.write('output.xml')
View Code1
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 #在country内添加(append)节点year2
 2 import xml.etree.ElementTree as ET
 3 tree = ET.parse("a.xml")
 4 root=tree.getroot()
 5 for country in root.findall('country'):
 6     for year in country.findall('year'):
 7         if int(year.text) > 2000:
 8             year2=ET.Element('year2')
 9             year2.text='新年'
10             year2.attrib={'update':'yes'}
11             country.append(year2) #往country节点下添加子节点
12 
13 tree.write('a.xml.swap')
View Code2
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import xml.etree.ElementTree as ET
 2  
 3  
 4 new_xml = ET.Element("namelist")
 5 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
 6 age = ET.SubElement(name,"age",attrib={"checked":"no"})
 7 sex = ET.SubElement(name,"sex")
 8 sex.text = '33'
 9 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
10 age = ET.SubElement(name2,"age")
11 age.text = '19'
12  
13 et = ET.ElementTree(new_xml) #生成文档对象
14 et.write("test.xml", encoding="utf-8",xml_declaration=True)
15  
16 ET.dump(new_xml) #打印生成的格式
View Code3

configparser模块

day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 # 注释1
 2 ; 注释2
 3 
 4 [section1]
 5 k1 = v1
 6 k2:v2
 7 user=egon
 8 age=18
 9 is_admin=true
10 salary=31
11 
12 [section2]
13 k1 = v1
View Code
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import configparser
 2 
 3 config=configparser.ConfigParser()
 4 config.read('a.cfg')
 5 
 6 #查看所有的标题
 7 res=config.sections() #['section1', 'section2']
 8 print(res)
 9 
10 #查看标题section1下所有key=value的key
11 options=config.options('section1')
12 print(options) #['k1', 'k2', 'user', 'age', 'is_admin', 'salary']
13 
14 #查看标题section1下所有key=value的(key,value)格式
15 item_list=config.items('section1')
16 print(item_list) #[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]
17 
18 #查看标题section1下user的值=>字符串格式
19 val=config.get('section1','user')
20 print(val) #egon
21 
22 #查看标题section1下age的值=>整数格式
23 val1=config.getint('section1','age')
24 print(val1) #18
25 
26 #查看标题section1下is_admin的值=>布尔值格式
27 val2=config.getboolean('section1','is_admin')
28 print(val2) #True
29 
30 #查看标题section1下salary的值=>浮点型格式
31 val3=config.getfloat('section1','salary')
32 print(val3) #31.0
读取  
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import configparser
 2 
 3 config=configparser.ConfigParser()
 4 config.read('a.cfg',encoding='utf-8')
 5 
 6 
 7 #删除整个标题section2
 8 config.remove_section('section2')
 9 
10 #删除标题section1下的某个k1和k2
11 config.remove_option('section1','k1')
12 config.remove_option('section1','k2')
13 
14 #判断是否存在某个标题
15 print(config.has_section('section1'))
16 
17 #判断标题section1下是否有user
18 print(config.has_option('section1',''))
19 
20 
21 #添加一个标题
22 config.add_section('egon')
23 
24 #在标题egon下添加name=egon,age=18的配置
25 config.set('egon','name','egon')
26 config.set('egon','age',18) #报错,必须是字符串
27 
28 
29 #最后将修改的内容写入文件,完成最终的修改
30 config.write(open('a.cfg','w'))
改写
day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)day16-常用模块(re、sys、subprocess、hashlib、shutil、xml、configparser)
 1 import configparser
 2   
 3 config = configparser.ConfigParser()
 4 config["DEFAULT"] = {'ServerAliveInterval': '45',
 5                       'Compression': 'yes',
 6                      'CompressionLevel': '9'}
 7   
 8 config['bitbucket.org'] = {}
 9 config['bitbucket.org']['User'] = 'hg'
10 config['topsecret.server.com'] = {}
11 topsecret = config['topsecret.server.com']
12 topsecret['Host Port'] = '50022'     # mutates the parser
13 topsecret['ForwardX11'] = 'no'  # same here
14 config['DEFAULT']['ForwardX11'] = 'yes'
15 with open('example.ini', 'w') as configfile:
16    config.write(configfile)
17 
18 基于上述方法添加一个ini文档
添加ini