标准库模块——re模块
re模块:
正则表达式内嵌在python中,并通过Re模块实现,被编译成一系列的字符码,然后由用C编写的匹配引擎执行。
特点:
功能是匹配字符串使用。
1. 可以动态模糊匹配。(搜索列表中王开头,两个字的人)
2. group可以直接取值。
3. 只要有返回值那么就表示已经匹配到,如果什么都没有那么就表示没有匹配到。
4. 如果有多个,只会匹配第一个就返回
re.match
会从头匹配字符串中取出从第一个字符开始是否符合规则,如果符合,就返回对象。用group取值,如果不符合,就返回None。
import re ret = re.match('<h1>(.*?)</h1>','<h1>123123abc</h1>') # ret = re.search('^<h1>.*?</h1>','<h1>123123abc</h1>') #相当于这样写了。 print(ret.group())
re.search
将匹配项中的第一个值取出,如果有值,那么可以使用group来取值。如果没有那么取值时就会报错。
import re ret = re.search('\d','<h1>123123abc</h1>') print(ret.group()) #只会匹配第一个值 #1
re.findall
返回所有值,所有匹配的字符以列表形式全部返回。未匹配则返回空。
import re ret = re.findall('\d','<h1>123123abc</h1>') print(ret) #无需group参数。 #['1', '1', '2', '3', '1', '2', '3', '1']
re.finditer
在得出的值超过一个的时候,能够有效的较低内存的消耗。将取得的值以迭代器的形式输出。
import re # ret = re.findall('\d','123123123'*2000000) #这样会占用大量的内存和处理时间。 ret = re.finditer('\d','123123123'*200000) for i in ret: print(i.group()) print(ret)
re.compile
如果一条正则表达式需要使用多次,那么可以使用complie来进行正则的编辑,编译后可以直接使用而不用再次编译。从而提高效率。
import re ret = re.compile('\d') #一次编译,多次使用,但只能用作相同的匹配模式时。 re1 = ret.findall('123123abc') re2 = ret.finditer('123123abc') re3 = ret.search('123123abc') print(re1) print(re2) print(re3)
re.split
根据正则匹配的字符进行切分,返回列表。
import re ret = re.split('\d','a1b2c3') print(ret) #['a', 'b', 'c', ''] 最后的空是因为3也匹配了,但分割的时候后面没有值则返回了一个空。 #默认不会保留匹配分割的内容,如果想要保留可以使用分组。 ret = re.split('(\d)','a1b2c') print(ret) #['a', '1', 'b', '2', 'c']
re.sub
替换正则匹配项。以字符串形式输出。
y=re.sub('[0-9]','|','xuan1ab2ca3c',count = 2) #匹配2次 print(y) xuan|ab|ca3c
re.subn
替换正则匹配项,并输出匹配次数,元组形式输出。
import re y=re.subn('[0-9]','|','xuan1ab2ca3c') print(y) #('xuan|ab|ca|c', 3)
flags的用法:
re.search("[a-z]+","abcdASD",flags=)
flags=re.I: 忽略大小写(括号内是完整写法) flags=M: 多行模式,改变'^'和'$'的行为 flags=S: 改变'.'的行为,任意匹配模式(包括换行符)默认不匹配换行符
re模块中,(分组)的妙用。
在re模块可以先匹配特定范围内,然后再使用分组来针对性提取想要的内容。
import re ret = re.findall('<h>.*?</h>','3211123ac<h>abc123abc</h>123aasfx')#首先匹配一定范围内 ret1 = re.findall('<h>(.*?)</h>','3211123ac<h>abc123abc</h>123aasfx')#再用分组来提取特定的值 print(ret1)
分组+search
import re ret = re.search('<h1>(.*?)</h1>','<h1>abc123abc321</h1>') print(ret.group()) #不显示特定分组内容。 #<h1>abc123abc321</h1> print(ret.group(1)) #当search应用分组后,会在group中添加分组提取的内容。group不写是0. #abc123abc321
分组+findall
import re ret = re.findall('\d(\d)\d','123abc123') print(ret) #只会将分组中的值进行提取打印。 #['2', '2']
分组+split
import re ret = re.split('\d(\d)\d','123abc321') print(ret) # 首先匹配3个数字,那么有123和321两个,在进行切割,再将分组提取出来。 #['', '2', 'abc', '2', '']
re模块中,( ?)的妙用
分组+?P == 分组命名
import re ret = re.search('(?P<tag>\d).*','a1b2c3') #(?P<tag>\d) 给\d来做命名 print(ret.group()) #1b2c3 print(ret.group('tag')) #1
分组+?P=命名 == 引用分组
一般用户前后对称式的查找方式时使用。
ret = re.search('(?P<tag><h1>).*?(?P=tag)','<h1>123abc123<h1>') #(?P=tag) #必须要和前面所命名的字符一样才行。否则为None print(ret.group())
分组+?: == 取消分组优先显示
ret = re.findall('(?:<h1>).*','<h1>123abc123<h1>') print(ret) #取消分组优先显示,分组只是以个正则的分组特性。['<h1>123abc123<h1>'] ret = re.findall('(<h1>).*','<h1>123abc123<h1>') print(ret) #分组优先,则只会显示分组内的内容。['<h1>']