正则:re regex。专业做字符串查找筛选。比’’,find()强大的多。有自己专业的语法。优点:功能最为强大。缺点;学习曲线陡峭。
场景:爬虫、网页解析。匹配、flask django框架的路由就是基于正则
regex 三方包,功能比内置的re包更强大
前缀r,raw原始字符串,运行中不需要处理转义字符
print(‘abc\nabc’) print(r’abc\nabc’)→abc\nabc
1. re函数方法总结
方法名称 | 格式 | 说明 |
---|---|---|
findall | re.findall(表达式, 字符串) | 返回所有满足匹配条件的结果,放在列表 |
search | re.search(表达式, 字符串).groups() | 函数会在字符串内查找模式匹配,直到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None |
match | re.match(表达式, 字符串).groups() | 同search,不过只在字符串开始处进行匹配 |
split | re.split(表达式, 字符串) | 按表达式对字符串进行分割,返回列表 |
sub | re.sub(表达式, 替换字符,字符串, count) | 按表达式类型替换成新的字符,返回字符串 |
subn | re.subn(表达式,替换字符, 字符串, count) | 按表达式类型替换新的字符串,返回元组,存放着替换结果和替换次数 |
compile | re.compile(表达式) | 将正则表达式编译成为一个 正则表达式对象 |
finditer | re.finditer(表达式, 字符串) | finditer返回一个存放匹配结果的迭代器 |
2. 贪婪匹配
贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪模式。
正则 | 待批评字符 | 匹配结果 | 说明 |
---|---|---|---|
<.*> | <script>…<\script> | <script…<\script> | 默认为贪婪模式, 会匹配尽量长的字符串 |
<.*?> | r’\d’ | <script> <script> | 加上?为将贪婪匹配模式转为非贪婪匹配模式,会尽量匹配短的字符 |
几个常用的非贪婪匹配模式:
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n, m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
.*? 的用法:
. 是任意字符
- 是取0至无限长度
? 是非贪婪模式。
合在一起就是 取尽量少的任意字符,一般不会这样单独写,他大多用在: .*?x
就是取前面任意长度的字符,直到一个x出现
#(1)findall
import re
ret = re.findall('\d','adsf123456we7we')
#匹配字符串中是数字的字符,并将匹配值返回到列表中
print(ret)
#['1', '2', '3', '4', '5', '6', '7']
#(2) search
ret = re.search('\d','adsf123456we7we').group()
#按照表达式匹配到第一个值就返回
print(ret) # 1
#3)match
ret = re.match('\w','adsf123456we7we').group()
#按照表达式匹配开头第一个值,符合的话就返回,不符合就报错
print(ret) # a
#(4)sub
ret = re.sub('\d','*','adsf123456we7we',0)
#匹配字符串中的数字,并且替换成*号,0表示替换所有
print(ret) # adsf******we*we
te = 'Tina is a good girl, she is cool, clever, and so on...'
pat = re.compile(r'\w*oo\w*')
print(pat.findall(te))
#['good', 'cool'] 查找所有包含'oo'的单词
#compile() 编译正则表达式模式,返回一个对象的模式。 pattern:编译时用的表达式字符串
#(5)subn
ret = re.subn('\d','*','adsf123456we7we',0)
#匹配字符串中的数字,并且替换成*号,返回一个元组,存放这替换结果和替换次数
print(ret) # ('adsf******we*we', 7)
#(6)compile
obj = re.compile('\d') #将正则表达式编译成一个正则表达式对象
ret = obj.search('ads123asd456').group()
print(ret) # 1
#(7)finditer
ret = re.finditer('\d', 'adsf451we15615adf16')
#finditer返回一个存放匹配结果的迭代器
print(ret)
for i in ret:
print(i.group())
#<callable_iterator object at 0x000002035EEEE0B8>
# 4
# 5
# 1
# 1
# 5
# 6
# 1
# 5
# 1
# 6
import re
# find() 简单但功能有限不方便
html = r'<html><body><h1>hello world</h1></body></html>'
start_index = html.find('<h1>')
end_index = html.find('</h1>')
print(html[start_index: end_index+1])
# <h1>hello world<
# 1》匹配固定字符串1次
key = r'javapythonUIVRpythonjava'
patten = re.compile(r'python')
matcher1 = re.search(patten, key)
print(matcher1)
print(matcher1[0]) # python
# compile(正则规则) 返回包含规则的匹配器对象。
# re.search(匹配器对象,待查找字符串)
# 2》任意字符串 .匹配任意字符 +修饰前面的匹配规则重复一次或多次 .+匹配一个或多个任意字符
key2 = r'<h1>hello world</h1>'
patten2 = re.compile(r'<h1>.+</h1>')
matcher2 = re.search(patten2, key2)
print(matcher2[0]) # <h1>hello world</h1>
# 3》匹配 点 加号 转义\
key3 = r'1968608841@qq.com'
patten3 = re.compile(r'.+\.com') # 判断用户输入是否qq邮箱 .+不太准确
matcher3 = re.search(patten3, key3)
print(matcher3[0]) # 1968608841@qq.com
# 4> * 前面的字符出现0次或多次
key4 = r'http://www.baidu.com https://www.baidu.com '
p4 = re.compile(r'https*://')
m4 = re.search(p4, key4)
matcher4 = p4.findall(key4)
print(matcher4) # ['http://', 'https://']
# 匹配器.findall(带匹配字符串) 返回列表
# 5>[Aa]匹配一个字符 中括号里任意一个字符符合就算匹配到
key = r'SelectSELECT' # sql大小写不敏感
pa5 = re.compile(r'[Ss][Ee][Ll][Ee][Cc][Tt]')
print(pa5.findall(key)) # ['Select', 'SELECT']
# 6> 排除
key6 = r'mat cat hat pat'
pa6 = re.compile(r'[^p]at')
print(pa6.findall(key6)) # ['mat', 'cat', 'hat']
# 7> 如果符合条件默认匹配尽可能多的字符。贪婪模式
key7 = r'1968608841@163.com.cn'
p7 = re.compile(r'.+@.+\.')
print(p7.findall(key7)) # ['1968608841@163.com.']
# 8》 惰性匹配 +?符合任意多字符的情况下 字符最少的
p8 = re.compile(r'.+@.+?\.')
print(p8.findall(key7)) # ['1968608841@163.']
# 9> 固定次数
key9 = r'saas and sas and saaas'
p9 = re.compile(r'sa{1,2}s')
print(p9.findall(key9)) # ['saas', 'sas']
# 10> 匹配换行后的内容 re.S
key10 = r"""
aaahelloaaa
bbb
world
aaa
"""
p10 = re.compile(r'hello.*?world', re.S)
print(p10.findall(key10))
# ['helloaaa\nbbb\nworld']
# 11> 分组 (子正则式) 返回元组,每一项对应每一个子正则式匹配的结果
key11 = r""" hello小明worldaaa """
p11 = re.compile(r'hello(.*?)world(.*?)')
print(p11.findall(key11))
# [('小明', '')]
p11 = re.compile(r'hello(.*?)world')
# [('小明')]