re模块
一:什么是正则?
正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
生活中处处都是正则:
比如我们描述:4条腿
你可能会想到的是四条腿的动物或者桌子,椅子等
继续描述:4条腿,活的
就只剩下四条腿的动物这一类了
二:常用匹配模式(元字符)
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'))
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'))
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
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())
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)
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结果是组内的结果,且是最后一个组的结果
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:修改模式
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模块
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解码
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值
import
导入hash用法
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 '''
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
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 和 内容 进行进一步的处理然后再加密:
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
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模块
#高级的 文件、文件夹、压缩包 处理模块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的意思是排除
1 import shutil 2 3 shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) 4 5 ''' 6 通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
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')
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')
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压缩解压缩
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压缩解压缩
xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml的格式如下,就是通过<>节点来区别数据结构的:
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协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:
print(root.iter('year')) #全文搜索
print(root.find('country')) #在root的子节点找,只找一个print(root.findall('country')) #在root的子节点找,找所有
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')
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')
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) #打印生成的格式
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
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
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'))
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文档