python基础——16(re模块,内存管理)
2024-08-30 12:37:28
一、内存管理
1、垃圾回收机制
不能被程序访问到的数据,就称之为垃圾。
1.1、引用计数
引用计数是用来记录值的内存地址被记录的次数的。
每一次对值地址的引用都使该值的引用计数+1;每一次对值地址的释放都使其引用计数-1;当一个值的引用计数为0时,就会被系统的垃圾回收机制回收。
1.2、循环导入:
# 循环引用,内存泄漏
ls1 = [666]
ls2 = [888]
ls1.append(ls2)
ls2.append(ls1)
print(ls1) # [666, [888, [...]]]
print(ls2) # [888, [666, [...]]]
print(ls1[1][1][0]) # 666
循环导入会使某些值的引用计数总是大于1.
1.3、标记删除
标记:标记的过程其实就是遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活。
删除:删除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉
1.4、分代回收
分代:指的是根据存活时间为来变量划分不同等级(也就是不同的代)
新定义的变量,放到新生代这个等级中,假设每隔1分钟扫描新生代一次,如果发现变量依然被引用,那么该对象的权重(权重本质就是个整数)加一,当变量的权重大于某个设定得值(假设为3),会将它移动到更高一级的青春代,青春代的gc扫描的频率低于新生代(扫描时间间隔更长),假设5分钟扫描青春代一次,这样每次gc需要扫描的变量的总个数就变少了,节省了扫描的总时间,接下来,青春代中的对象,也会以同样的方式被移动到老年代中。也就是等级(代)越高,被垃圾回收机制扫描的频率越低
回收:依然是使用引用计数作为回收的依据。
二、re模块
正则表达式:有语法的字符串
重点:
1、正则就是字符串
2、正则语法
3、分组
4、python中re的常用方法
2.1、常用的正则表达式:
| 元字符 | 描述 |
| ----------- | :----------------------------------------------------------- |
| \ | 将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\\n”匹配\n。“\n”匹配换行符。序列“\\”匹配“\”而“\(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。 |
| ^ | 匹配输入字行首。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 |
| $ | 匹配输入行尾。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。 |
| * | 匹配前面的子表达式任意次。例如,zo*能匹配“z”,也能匹配“zo”以及“zoo”。*等价于{0,}。 |
| + | 匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 |
| {*n*} | *n*是一个非负整数。匹配确定的*n*次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。 |
| {*n*,} | *n*是一个非负整数。至少匹配*n*次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。 |
| {*n*,*m*} | *m*和*n*均为非负整数,其中*n*<=*m*。最少匹配*n*次且最多匹配*m*次。例如,“o{1,3}”将匹配“fooooood”中的前三个o为一组,后三个o为一组。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。 |
| ? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”。?等价于{0,1}。 |
| ? | 当该字符紧跟在任何一个其他限制符(*,+,?,{*n*},{*n*,},{*n*,*m*})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少地匹配“o”,得到结果 ['o', 'o', 'o', 'o'] |
| .点 | 匹配除“\n”和"\r"之外的任何单个字符。要匹配包括“\n”和"\r"在内的任何字符,请使用像“[\s\S]”的模式。 |
| | |
| x\|y | 匹配x或y。例如,“z\|food”能匹配“z”或“food”(此处请谨慎)。“[zf]ood”则匹配“zood”或“food”。 |
| [xyz] | 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。 |
| [^xyz] | 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”任一字符。 |
| [a-z] | 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身. |
| [^a-z] | 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。 |
| \b | 匹配一个单词的边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的)。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”;“\b1_”可以匹配“1_23”中的“1_”,但不能匹配“21_3”中的“1_”。 |
| \B | 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er” |
| \s | 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。 |
| \S | 匹配任何可见字符。等价于[^ \f\n\r\t\v]。 |
| \w | 匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。 |
| \W | 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。 |
| \d | 匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持 |
| \D | 匹配一个非数字字符。等价于[^0-9]。grep要加上-P,perl正则支持 |
| \n | 匹配一个换行符。等价于\x0a和\cJ。 |
| \r | 匹配一个回车符。等价于\x0d和\cM。 |
| \t | 匹配一个制表符。等价于\x09和\cI。 |
| ( ) | 将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。 |
| (?:pattern) | 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(\|)”来组合一个模式的各个部分时很有用。例如“industr(?:y\|ies)”就是一个比“industry\|industries”更简略的表达式。 |
| \| | 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him\|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。 |
2.2、常用的匹配语法:
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换
2.3、代码示例:
import re
# part1
s = "123454http://www.baidu.com/12htp46"
res = re.findall(r'http://www.baidu.com/', s)
print(res)
# part2
# 2.1 转义
print(re.findall(r'\\a',r'123\abc')) # 用来转义,在正则中\\代表匹配\
# 2.2单个字符
print(re.findall(r'.','123[\a b\nc\ta\rbcABC好好*_12')) # .匹配所有单个字符(刨除换行)
print(re.findall(r'\s','123[\a b\nc\ta\rbcABC好好*_12')) # 匹配所有空白、制表符、换行符、回车符
print(re.findall('\S','123[\a b\nc\ta\rbcABC好好*_12')) # 匹配任何可见字符
print(re.findall('\w',r'123[\a b\nc\ta\rbcABC好好*_12')) # 匹配字母+数字+下划线
print(re.findall('[A-Za-z0-9好]',r'123[\a b\nc\ta\rbcABC好好*_12')) # 匹配前面集合内的
print(re.findall(r'[A-Z]|[a-z]', r'123[\abcabcABC')) # 匹配前面集合或后面集合的单个字符
print(re.findall(r'[0-9]', r'123\abcabc')) # 匹配区间的数字,单个列出
print(re.findall(r'\D',r'123\abcacb')) # 匹配非数字的
print(re.findall(r'\d',r'123\abcccc')) # 匹配数字
print(re.findall(r'a', r'123\abcabc')) # 匹配单个字符
# 2.3、多个字符
print(re.findall(r'zo*?',r'zzozoozooo')) # {0,n} 0到n个,非贪婪匹配,尽可能少的匹配 == {0}
print(re.findall(r'zo*',r'zzozoozooo')) # {,n} 0到n个,贪婪匹配,尽可能多的匹配
print(re.findall(r'zo+?',r'zzozoozooo')) # {1,n} 1到n个,非贪婪匹配,尽可能少的匹配 == {1}
print(re.findall(r'zo+',r'zzozoozooo')) # {1,n} 1到n个,贪婪匹配,尽可能多的匹配
print(re.findall(r'zo?',r'zzozoozooo')) # {0,1} 0到1个,贪婪匹配,尽可能多的匹配
print(re.findall(r'o{1,2}', r'foodfoood')) # {n,m} n到m个,贪婪匹配,尽可能多的匹配
print(re.findall(r'o{2,}',r'foodfoood')) # {n, } n到多个,贪婪匹配,尽可能多的匹配
print(re.findall(r'[a-z]{2}', r'123\abcabc')) # {n} n代表个数,按游标匹配
print(re.findall(r'ab', r'123\abcabc'))
# 多行匹配
# 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))
# part3
# 分组
# 1、从左往右数(进行编号,自己的分组从1开始,group(0)代表匹配到的目标整体
# 2、(?: ... ):取消所属分组,()就是普通(),可以将里面的信息作为整体包裹,但不产生分组
regexp = re.compile('(?:(?:http://)\((.+)\)/)') # 生成正则对象
target = regexp.match('http://(www.baidu.com)/')
print(target.group(1))
# 多行
result = re.findall(r'^http://.+$','http://www.baidu.com/\nhttp://www.sina.com.cn/', re.M)
print(result)
for res in result:
t = re.match('http://(.+)/',res)
print(t.group(1))
# part4
# 替换
# 1.不参与匹配的原样带下 2.参与匹配的都会被替换为指定字符串
# 3.在指定字符串值\num拿到具体分组 4.其他字符串信息都是原样字符串
print(re.sub('《(?:[a-z]+)(\d+)(.{2})', r'\\2abc\2\1', '《abc123你好》'))
print(re.sub('[0-9]+', '数字', 'abc123你好'))
print(re.split('\s', '123 456\n789\t000'))
res = re.search("(abc){2}(\|\|=){2}","alexabcabc||=||=")
print(res) #<_sre.SRE_Match object; span=(4, 16), match='abcabc||=||='>
print(res.groups()) #('abc', '||=')
print(res.group()) #abcabc||=||=
res1 = re.search("(?P<id>[0-9]+)(?P<name>[a-zA-Z]+)","abcd123456def")
print(res1.groupdict()) #{'name': 'def', 'id': '123456'}
res2 = re.search("(?P<province>[0-9]{2})(?P<city>[0-9]{4})(?P<birthday>[0-9]{8})","622801199508231415")
print(res2.groupdict()) #{'city': '2801', 'birthday': '19950823', 'province': '62'}
res4 = re.split("[0-9]+","abc12def4gh5ijk")
print(res4) #['abc', 'def', 'gh', 'ijk']
res5 = re.sub("[0-9]","|","abc12de3f4g5")
print(res5) #abc||de|f|g|
res6 = re.sub("[0-9]","|","abc12de3f4g5",count=2)
print(res6) #abc||de3f4g5
print(re.search("[a-z]+","abcDEF",flags=re.I).group()) #忽略大小写
最新文章
- Python标准模块--collections
- Android四大组件之Activity一(组件的概念、Intent、监听)
- Android Programming: Pushing the Limits -- Chapter 6: Services and Background Tasks
- 十八、【开源】EnterpriseFrameWork框架核心类库之Winform控制器
- Vrrp协议
- tomcat 默认项目设置
- 17.1.1.4 Obtaining the Replication Master Binary Log Coordinates 得到复制master binary log 位置:
- .net程序员必须知道的知识
- Codeforces 362D Fools and Foolproof Roads 构造题
- C#6.0新特性之字符串嵌入 String Interpolation
- 《JS权威指南学习总结--8.3 函数的实参和形参》
- Mysql中主从复制的原理、配置过程以及实际案例
- BOM总结
- 兜转数年,老跳成了卖过软件开过店写过APP的电脑老师
- interface接口
- webpack 命令行 传入自定义变量
- 1122 Hamiltonian Cycle (25 分)
- zw版【转发&#183;台湾nvp系列Delphi例程】HALCON HomMat2dRotate2
- redis配置密码认证,通过密码可以进行连接
- 利用Runloop优化流畅度