内存管理 re模块
# 内存垃圾回收机制: # 工作原理:引用计数 # 引用就+1 释放就是-1 当计数为0时 就会被垃圾回收机制回收 # 标记清除:解决循环引用导致的内存泄漏 # 标记:GC roots可以直接或间接访问到的数据,都标记为存活状态 # 清除:触发标记清楚动作后,将所有存活状态的变量复制到新空间,将老空间中的所有值清空 # 分代回收:提高回收效率的优化策略 # 分代:将产期存活的变量移至更高代,检查频率降低 # 回收:回收的依据还是采用引用计数 # 循环引用 => 内存泄漏 # ls1 = [666] # ls2 = [888] # ls1.append(ls2) # ls2.append(ls1) # print(ls1) [666, [888, [...]]] # print(ls2)[888, [666, [...]]] # re 正则 # 一什么是正则? # 正则就是用一些具有特殊含义的符号组合到一起(称之为正则表达式)来描述字符或者字符串的方法 # 或者说:正则就是用来描述一类事物的规则,(在python中)它内嵌在python中,并通过re模块实现。正则表达式模式被编译成一系列的字节码。然后由c编写的皮匹配引擎执行 # 二常用匹配模式(元字符) # \w 匹配字母数字及下划线 # \W 匹配非字母数字下划线 # \s 匹配任意空白字符 等价于[\t\n\r\f] # \S 匹配任意非空字符 # \d 匹配任意数字,等价于[0-9] # \D 匹配任意非数字 # \A 匹配字符串开始 # \Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串 # \z 匹配字符串结束 # \G 匹配最后匹配完成的位置 # \n 匹配一个换行符 # \t 匹配一个制表符 # ^ 匹配字符串的开头 # $ 匹配字符串的末尾 # . 匹配任意字符,除来换行符,当re.DOTALL标记被指定是,则可以匹配包含换行符的任意字符 # [...] 用来表示一组字符,单独列出来:[amk] 匹配 'a','m'或'k' # [^....] 不在[]的字符: [^abc]: 匹配除了a b c 之外的字符 # * 匹配0个或多个表达式 # + 匹配1个或多个的表达式 # ? 匹配0个或1个有前面的正则表达式定义的片段,非贪婪方式 # {n} 精确匹配n个前面表达式 # {n,m} 匹配n到m次由前面的正则表达式定义的片段,贪婪方式 # a|b 匹配a或b # () 匹配括号内的表达式,也表示一个组 import re # s="12345http://www.baidu.com/12htp46" # res=re.findall(r'http://www.baidu.com/',s) # print(res) #['http://www.baidu.com/'] # 转义 # print(re.findall(r'\\a',r'123\adc')) #['\\a'] 用来转义,在正则中\\a代表\a 原义的字符串前面要加r # print(re.findall('a',r'123\abcabc')) #['a', 'a'] 字母 # print(re.findall('\d',r'123\abcabc')) #['1', '2', '3'] 数字 # print(re.findall('\D',r'123\abcabc')) #['\\', 'a', 'b', 'c', 'a', 'b', 'c']非数字 # print(re.findall('[0-9]',r'123\abcabc')) #['1', '2', '3'] 匹配任意一个数字 # 列表中-在中间表示从0到9之间的数字 [- 0 9 ]或者[0 9 -] 表示匹配列表中 - 0 9 三个中的任意一个 # print(re.findall('[A-z]|[a-z]',r'123\abcabcABC')) # #['\\', 'a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C'] ascii码表中[65-122]|[97-122]包含\ # print(re.findall('[A-Z]|[a-z]',r'123\abcabcABC')) # #['a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C'] # print(re.findall('[0-3]|[6-9]',r'123\abcabcABC48')) # #['1', '2', '3', '8'] # print(re.findall('[A-Za-z0-9好]',r'123[\abcabcABC好好')) # #['1', '2', '3', 'a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C', '好', '好'] # print(re.findall('\w',r'123[\abcabcABC*_12')) # #['1', '2', '3', 'a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C', '_', '1', '2'] 字母数字下划线 # print(re.findall('\S',r'123[\abcabcABC好好*_12')) #任意非空字符 # ['1', '2', '3', '[', '\\', 'a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C', '好', '好', '*', '_', '1', '2'] # print(re.findall('\s','123[\n\t\r\abcabcABC好好*_12')) #匹配所有任意空白字符 # ['\n', '\t', '\r'] # print(re.findall('.','123[\a b\nc\ta\rbcABC好好*_12')) #匹配任意字符 除了换行符 # ['1', '2', '3', '[', '\x07', ' ', 'b', 'c', '\t', 'a', '\r', 'b', 'c', 'A', 'B', 'C', '好', '好', '*', '_', '1', '2'] # print(re.findall('.','\a')) #['\x07'] # print(re.findall('ab',r'123\abcabc')) #['ab', 'ab'] # print(re.findall('[a-z]{2}',r'123\abcabc')) #['ab', 'ca', 'bc'] {n} n代表个数 a-z中的任意两个 # print(re.findall('o{2,}','foodfooood')) #['oo', 'oooo'] {n,}n到多个 贪婪匹配 尽可能的多的匹配 # print(re.findall('o{1,2}','foodfooood')) #['oo', 'oo', 'oo'] {n,m} n到m个贪婪匹配,尽可能多的匹配(1到2个) # print(re.findall('zo*','zzozoozooo')) # ['oo', 'oo', 'oo'] {,n} 0到n个 贪婪匹配 # print(re.findall('zo+','zzozoozooo')) #['zo', 'zoo', 'zooo'] {,n} 1到n个 贪婪匹配 # print(re.findall('zo?','zzozoozooo')) #['z', 'zo', 'zo', 'zo'] {0,1} 0到1个,贪婪匹配,尽可能多的匹配 # print(re.findall('zo+?','zzozoozooo')) #['zo', 'zo', 'zo'] {1,n} 1到n个,非贪婪匹配,尽可能少的匹配 == {1} # print(re.findall('zo*?','zzozoozooo')) #['z', 'z', 'z', 'z'] {0,n} 1到n个,非贪婪匹配,尽可能少的匹配 == {0} # 多行匹配 # re.S 将\n也能被.匹配 re.I :不区分大小写 re.M 结合^ $ 来使用,完成多行匹配 # print(re.findall('^owen.+vv$','owen_name_vv\nowen_age_vv\nzero_owen\nowen_oo',re.M)) # ['owen_name_vv', 'owen_age_vv'] # result=re.findall(r'^http://.+/$','http://www.baidu.com/\nhttp://www.sina.com.cn/',re.M) # print(result) # ['http://www.baidu.com/', 'http://www.sina.com.cn/'] # for res in result: # print(res) # http: // www.baidu.com / # http: // www.sina.com.cn / # t=re.match('http://(.+)/',res,) #相当于search的从头开始找 # print(t) # t=re.match('http://(.+)/',res,).group() # print(t) # http: // www.baidu.com / # http: // www.sina.com.cn / # <re.Match object; span=(0, 21), match='http://www.baidu.com/'> # <re.Match object; span=(0, 23), match='http://www.sina.com.cn/'> # print(t.group(0)) # group(0)代表的是('http://(.+)/) 0:最外层的括号 # <re.Match object; span=(0, 21), match='http://www.baidu.com/'> # <re.Match object; span=(0, 23), match='http://www.sina.com.cn/'> # print(t.group(1)) # group(1)代表的是('http://(.+)/) 1:最外层的里面的左边的第一个左括号( # www.baidu.com # www.sina.com.cn # 分组: # 1从左往右数 " ( " 进行编号,自己的分组从1开始,group(0)代表匹配的目标整体 # 2.(?:....):取消所属分组,()就是普通的括号,可以将里面的信息作为整体包裹,但不产生分组 # regexp = re.compile ('(?:(?:http://)\((.+)\)/)') #\( \) 转义成括号 # target=regexp.match('http://(www.baidu,com)/') # print(target.group(0)) #http://(www.baidu,com)/ #将里面的信息作为整体包裹,但不产生分组 # print(target.group(1)) #www.baidu,com # 替换: # 1.不参与匹配的原样带下 2 参与匹配的都会被替换为指定字符串 # 3 在不指定字符串值 \num拿到具体分组 4 其他字符串信息都是原样字符串 # print(re.sub('《(?:[a-z]+)(\d+)(.{2})',r'\0\2abc\2\1','《abc123你好》')) # 0:《abc 1:(123) 2:(你好) 》取不到不参与替换原样带下 # 你好abc你好123》 # print(re.sub('《(?:[a-z]+)(\d+)(.{2})',r'\1\2','《abc123你好》')) # print(re.findall('[a-z]{2}',r'123\abcabce')) #['ab', 'ca', 'bc'] {n} n代表个数 a-z中的任意两个 # ['ab', 'ca', 'bc'] import re # print(re.findall('\w','ab 12\+-*&_')) #['a', 'b', '1', '2', '_'] # print(re.findall('\W','ab 12\+-*&_')) # [' ', '\\', '+', '-', '*', '&'] # print(re.findall('\S','ab\r1\n2\t\+-*&_')) #非空字符串 # ['a', 'b', '1', '2', '\\', '+', '-', '*', '&', '_'] # print(re.findall('\s','ab\r1\n2\t\+-*&_')) #匹配任意空字符串['\r', '\n', '\t'] # print(re.findall('\d','ab\r1\n2\t\+-*&_')) #['1', '2'] # print(re.findall('\D','ab\r1\n2\t\+-*&_')) #任意非数字 # ['a', 'b', '\r', '\n', '\t', '\\', '+', '-', '*', '&', '_'] # print(re.findall('\w_sb','egon alex_sb123123wxx_sb,lxx_sb')) # 字母数字下划线 ['x_sb', 'x_sb', 'x_sb'] # print(re.findall('\Aalex','abcalex is salexb')) # 匹配字符串开始 [] # print(re.findall('\Aalex','alex is salexb')) #匹配字符串开始 ['alex'] # print(re.findall('^alex','alex is salexb')) #匹配字符串的开头 ['alex'] # print(re.findall('sb\Z','alexsb is sblalexbsb')) #匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串['sb'] # print(re.findall('sb$','alexsb is sbalexbsb')) # 匹配字符串末尾['sb'] # print(re.findall('^ebn$','ebn1')) #匹配开头 匹配结尾[] # print(re.findall('a\nc','a\nc a\tc alc')) #['a\nc'] # 重复匹配 # . ? * + {m,n} .* .*? # 1 . 代表除了换行符外的任意一个字符 # print(re.findall('a.c','abc alc aAc aaaaa\nc')) #['abc', 'alc', 'aAc'] # print(re.findall('a.c','abc alc aAc aaaaca\nc',re.DOTALL)) # ['abc', 'alc', 'aAc', 'aac', 'a\nc'] # 2 ? 代表左边那一个字符重复0次或1次 # print(re.findall('ab?','a ab abb abbb abbbbb')) #['a', 'ab', 'ab', 'ab', 'ab'] # 3 * 代表左边那一个字符出席那0次或无穷次 # print(re.findall('ab*','a ab abb abbb abbbb')) #['a', 'ab', 'abb', 'abbb', 'abbbb'] # 4 + 代表左边那一个字符出现1次或无穷次 # print(re.findall('ab+','a ab abb abbba abbbbb')) #['ab', 'abb', 'abbb', 'abbbbb'] # 5 {m,n}:代表左边那一个字符出现m次到n次 # print(re.findall('ab?','a ab abb abbbbb ')) #['a', 'ab', 'ab', 'ab'] # print(re.findall('ab{0,1}','a ab abb abbbbb ')) #['a', 'ab', 'ab', 'ab'] # print(re.findall('ab*','a ab abb abbb abbb abbbbb')) # ['a', 'ab', 'abb', 'abbb', 'abbb', 'abbbbb'] # print(re.findall('ab{0,}','a ab abb abbb abbb abbbbb')) # ['a', 'ab', 'abb', 'abbb', 'abbb', 'abbbbb'] # print(re.findall('ab+','a ab abb abbbb abbbb')) # ['ab', 'abb', 'abbbb', 'abbbb'] # print(re.findall('ab{1,}','a ab abb abbbb abbbb')) # ['ab', 'abb', 'abbbb', 'abbbb'] # print(re.findall('ab{1,3}','a ab abb abbb abbbbbb')) # ['ab', 'abb', 'abbb', 'abbb'] # 6 .* 匹配任意长度, 任意的字符 =>贪婪匹配 # print(re.findall('a.*c','ac a123c aaaac a*123)()c asdfdffdf')) # ['ac a123c aaaac a*123)()c'] # 7 .*? :非贪婪匹配 {0,1}最少为零个中间值 # print(re.findall('a.*?c',' ac a123c456c')) #['a123c'] # ():分组 # print(re.findall('(alex_sb)','alex_sb asdfgdsfdsfh_sb')) # ['alex'] 只返回匹配到的括号内的内容 # print(re.findall( # 'herf="(.*?)"', # '<li><a id="blog_nav_sitehome" class="menu" href="http://www.cnblogs.com/">博客园</a></li>' # )) # [] 最少0个 # []:匹配一个指定返回内的字符(这一个字符来自于括号内定义的) # print(re.findall('a[0-9][0-9]c','alc a+c a2c a9c allc a-c acc aAc')) # [] # 当需要被当众普通符号匹配时,只嗯能放到[]的最左边或最右边 import re # print(re.findall('a[- + *]c', 'alc a+c a2c a9c a*c allc a-c acc aAc')) # ['a+c', 'a*c', 'a-c'] # print(re.findall('a[a-zA-Z]c','alc a+c a2c a9c a*c allc a-c acc aAc')) # ['alc', 'acc', 'aAc'] # []内的^代表取反的意思 # print(re.findall('a[^a-zA-Z]c','alc a+c a2C a9c a*c allc a-c acc aAc')) # ['a+c', 'a9c', 'a*c', 'a-c'] # print(re.findall('a[^0-9]c','a c alc a+c a2c a9c a*c allc a-c acc aAc')) # ['a c', 'alc', 'a+c', 'a*c', 'a-c', 'acc', 'aAc'] # print(re.findall('([a-z]+)_sb','egon alex_sb123njjkjkjkjk_sb,lxx_sb')) # ['alex', 'njjkjkjkjk', 'lxx'] # |: 或者 # print(re.findall('compan(ies|y)','Too many companies have gone bankrupt,and the next one is my company')) # ['ies', 'y'] # (?:) 代表取匹配成功的所有内容,而不是仅仅只是括号内的内容 # print(re.findall('compan(?:ies|y)','Too many companies have gone bankrupt,and the next one is my company')) # ['companies', 'company'] # print(re.findall('alex|sb','alex sb sb asjkjkjkgon alex sb egon')) # ['alex', 'sb', 'sb', 'alex', 'sb'] # re模块的其他方法: # print(re.findall('alex|sb','123123 alex sb sfjdkklkgon alex sb egon ')) # print(re.search('alex|sb','123123 alex sb sfjdkklkgon alex sb egon ').group()) # print(re.search('^alex','123123 alex sb sfjdkklkgon alex sb egon ')) # ['alex', 'sb', 'alex', 'sb'] 找所有的 # alex search 从左往右找到第一个就停下 # None 从头开始匹配 不满足 # print(re.search('^alex', 'alex sb sadfsadfasdfegon alex sb egon').group()) # print(re.match('alex', '1alex sb sadfsadfasdfegon alex sb egon')) # alex 从头找 找到一个结束 # None 相当于search的从头开始匹配 不满足 # print(re.match('alex', 'alex sb sadfsadfasdfegon alex sb egon').group()) # print(re.match('alex', 'alex sb sadfsadfasdfegon alex sb egon')) # alex 从头开始匹配 满足 group取值 # <re.Match object; span=(0, 4), match='alex'> 从头开始匹配 满足 # print(re.match('alex', '123213 alex sb sadfsadfasdfegon alex sb egon')) # None # info='a:b:c:d' # print(info.split(':')) # print(re.split(':',info)) # ['a', 'b', 'c', 'd'] # ['a', 'b', 'c', 'd'] # info =r'get :a.txt\3333/rwx' # print(re.split('[:\\\/]',info)) # ['get ', 'a.txt', '3333', 'rwx'] # print('egon is beutifull egon'.replace('egon','EGON',1)) # EGON is beutifull egon # print(re.sub('(.*?)(egon)(.*?)(egon)(.*?)',r'\1\2\3EGON\5','123 egon is beauifull egon 123')) # (123 )(egon)( is beutifull )(egon)( 123) # 123 egon is beauifull EGON 123 # \1\2\3EGON\5 # print(re.sub('(lqz)(.*?)(SB)',r'\3\2\1','lqz is SB')) # SB is lqz # print(re.sub('([a-zA-Z)]+)([^a-zA-Z]+)([a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)',r'\5\2\3\4\1',r'lqzzzzz123+ is SB')) # SB123+ is lqzzzzz # pattern =re.compile('alex') # print(pattern.findall('alex is alex alex')) # print(pattern.search('alex is alex alex').group()) # print(pattern.match('alex is alex alex').group()) # print(pattern.findall('alexfjksdjgkjskdfj is alex alex')) # ['alex', 'alex', 'alex'] # alex # alex # ['alex', 'alex', 'alex']
操作分组的方法
(?P<name>...):有名分组
返回值是math匹配的结果对象,可以 .group(组序号|组名)来取具体组的信息
res=re.match('(\d{3})(?P<center>\d{3})(\d{3})','123456789)
print(res.group('center'))
456
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# print(re.findall('\d*', '<123456789>')) # ['', '123456789', '', ''] #先匹配< 后匹配123456789 在匹配> 最后匹配整体 # 1、书写可以配身份证的正则表达式 # 身份证:18位 由17位数字本体码和1位校验码组成排列顺序从左至右依次为: # 六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 # [1-7][0-9]{5} #六位数字地址码 # (?:19[0-9]{2}|20[01][0-9]) # 1900-2019 # (?:0[0-9]|1[12]) #01-12 月 # (?:0[0-9]|[12][0-9]|3[01]) #01-31 天 # [0-9]{3} #三为数字顺序码 # [0-9Xx] #一位验证码 # [1-7][0-9]{5}(?:19[0-9]{2}|20[01][0-9])(?:0[0-9]|1[12])(?:0[0-9]|[12][0-9]|3[01])[0-9]{3}[0-9Xx] # 2 书写可以匹配邮箱的正则表达式 # 2530302605@qq.com \.转义点把它当成普通的.匹配 # [a-zA-Z0-9]\w{,15}@[176|178|192]\.[com|com\.cn|cn] # 获取百度首页图片地址 import re import requests responds=requests.get('http://www.baidu.com/') print(responds) content=responds.text # print(content) content+='http://www.baidu.com/wimg/gs.gif' res1_list=re.findall('www[^w]*?(?:gif|png)',content) print(res1_list) # ['www.baidu.com/img/bd_logo1.png', 'www.baidu.com/bdorz/login.gif', 'www.baidu.com/bdorz/login.gif', 'www.baidu.com/img/gs.gif'] res_list=re.findall('www.{1,30}(?:gif|png)',content) print(res_list) # ['www.baidu.com/img/bd_logo1.png', 'www.baidu.com/bdorz/login.gif', 'www.baidu.com/bdorz/login.gif', 'www.baidu.com/img/gs.gif', 'www.baidu.com/wimg/gs.gif'] #