垃圾回收机制与re正则
一、内存管理
1、垃圾回收机制:不能被程序访问到的数据称之为垃圾
2、引用计数:引用计数是用来记录值的内存地址被记录的次数
每一次对值地址的引用都可以使该值的引用计数 +1
每一次对值地址的释放都可以使该值的引用计数 -1
当一个值的引用计数为0时,该值就会被系统的垃圾回收机制回收
3、循环导入:循环导入会导致某些值的引用计数永远大于0
ls1 = [666] ls2 = [888] ls1.append(ls2) ls2.append(ls1) print(ls1) # [666, [888, [666, [...]]]] print(ls2) # [888, [666, [888, [...]]]] print(ls1[1][1][0]) # 666 print(ls2[1][1][0]) # 888
4、标记删除
把所有访问到的数据标记为存活状态,把所有的线程和栈区能访问到的,
对应堆区的空间标记为存活状态,阈值不会超过存储区域的一半,把所有的存活状态会
拷贝新的一份到新的内存空间中,当阈值空间不够了,会调用标记删除,把所有的存活状态会拷贝
新的一份到新的内存空间中,然后进行删除操作,把原来空间所有的内容都删除,一下干掉。
解析:
标记:标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),
然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象
删除:删除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉
5、分代回收
①分代:根据存活时间来为变量划分不同等级(也就是不同的代)
新生代 > 青春代 > 老年代
等级(代)越高,被垃圾回收机制扫描的频率越低
②回收:依然是使用引用计数作为回收的依据
解析:
新定义的变量,放到新生代这个等级中,假设每隔1分钟扫描新生代一次,如果发现变量依然被引用,
那么该对象的权重(权重本质就是个整数)加一,当变量的权重大于某个设定得值(假设为3),
会将它移动到更高一级的青春代,青春代的gc扫描的频率低于新生代(扫描时间间隔更长),
假设5分钟扫描青春代一次,这样每次gc需要扫描的变量的总个数就变少了,节省了扫描的总时间,
接下来,青春代中的对象,也会以同样的方式被移动到老年代中。也就是等级(代)越高,
被垃圾回收机制扫描的频率越低
二、re正则:重点:①定义②语法③分组④re常用方法
1、定义:有语法的字符串,用来匹配获取目标字符串中的指定需求字符串
import re #正则就是字符串,可以为原义的普通字符串 # s = '12345http://www.baidu.com/12htp46' # res = re.findall(r'//www.baidu.com/', s) # print(res) # ['//www.baidu.com/'] # 转义 # res = re.findall(r'\\a', r'123\abc') # print(res) # ['\\a'] # 用来转义,在正则中\\代表匹配\
2、语法:
①单个字符
# \d == [0-9] # \D == [^0-9] # \w == 字母+数字+_ # [0-9A-Za-z] == 所有字母+数字 # . == 匹配所有单个字符(刨除换行) print(re.findall(r'a', r'123\abc')) # ['a'] print(re.findall(r'\d', r'123\abc')) # ['1', '2', '3'] print(re.findall(r'[0-9]', r'123\abc')) # ['1', '2', '3'] print(re.findall(r'\D', r'123\abc')) # ['\\', 'a', 'b', 'c'] print(re.findall(r'[A-Z]|[a-z]', r'123abcABC')) # ['a', 'b', 'c', 'A', 'B', 'C'] print(re.findall(r'[A-Za-z0-9好]', r'123abcABC好')) # ['1', '2', '3', 'a', 'b', 'c', 'A', 'B', 'C', '好'] print(re.findall(r'\w', r'123[\abc好的*_A')) # 字母+数字+下划线 # ['1', '2', '3', 'a', 'b', 'c', '好', '的', '_', 'A'] print(re.findall(r'\S', r'123[\abc好的*_A')) # 字母+数字+_ 对立面 print(re.findall(r'\s', '123[ \nbc\好的*_A')) # 匹配所有空白、制表符、换行符、回车符 print(re.findall(r'.', r'AB好_*&12\ab')) # 匹配所有单个字符(刨除换行) # ['A', 'B', '好', '_', '*', '&', '1', '2', '\\', 'a', 'b']
②多个字符
print(re.findall(r'ab', r'123\abc')) # ['ab'] print(re.findall(r'[a-z]{3}', r'123\abcabc')) # {n} n代表个数 # ['abc', 'abc'] print(re.findall(r'o{1,2}', r'foodfoood')) # {n, } n到多个,贪婪匹配,尽可能多的匹配 # ['oo', 'oo', 'o'] print(re.findall(r'zo?', r'zzozoozooo')) # {0,1} 0到1个,贪婪匹配,尽可能多的匹配 # ['z', 'zo', 'zo', 'zo'] print(re.findall(r'zo+', r'zzozoozooo')) # # {1,n} 1到n个,贪婪匹配,尽可能多的匹配 # ['zo', 'zoo', 'zooo'] print(re.findall(r'zo*', r'zzozoozooo')) # # {,n} 0到n个,贪婪匹配,尽可能多的匹配 # ['z', 'zo', 'zoo', 'zooo']
③多行匹配
# re.S:将\n也能被.匹配 re.I:不区分大小写 re.M:结合^ $来使用,完成多行匹配 print(re.findall(r'^owen.+vv$', 'owen_name_vv\nowen_age_vv\nzero_owen\nowen_oo', re.M)) # ['owen_name_vv', 'owen_age_vv']
④分组
1、从左往右数数,进行编号,自己的分组从1开始,group(0)代表匹配到的目标整体
2、(?:...):取消所属分组,()就是普通(),可以将里面的信息作为整体包裹,但不产生分组
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: t = re.match('http://(.+)/', res) print(t.group(1)) # 结果为: # www.baidu.com/ # www.sina.com.cn/
regexp = re.compile('((http://)(.+)/)') # 生成正则对象,调用方法一样 target = regexp.match('http://www.baidu.com/') print(target.group(0)) # 匹配的目标整体 http://www.baidu.com/ print(target.group(1)) # 第一个分组 整体 http://www.baidu.com/ print(target.group(2)) # 第二个分组 http:// print(target.group(3)) # 第三个分组 www.baidu.com # 为什么要分组:要匹配目标字符串,但是不想要目标字符串的所有字符 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 # ?:?:删除两个分组,只剩下一个分组 目标字符串 www.baidu.com
⑤拆分
print(re.split('\s', '123 456\n789\t000')) # ['123', '456', '789', '000']
⑥替换
不参与匹配的原样带下
参与匹配的都会被替换为指定字符串
在指定字符串值\num拿到具体分组
其他字符串信息都是原样字符串
print(re.sub('《(?:[a-z]+)(\d+)(.{2})', r'\\2abc\2\1', '《abc123你好》')) # \2abc你好123》 print(re.sub('[0-9]+', '数字', 'abc123你好')) # abc数字你好 print(re.sub('[a-z]+', '字母', 'abc123你好')) # 字母123你好