day 24 内置模块re
1.正则表达式,匹配字符串
正则表达式是对字符串操作的一种逻辑公式.我们一般使用正则表达式对字符串镜子那个匹配和过滤,使用正则的优缺点:
优点: 灵活,功能性强,逻辑性强
缺点: 上手难.一旦上手,会爱上这个东西
工具:各大文本编辑器一般都有增则匹配功能.我们也可以去http://tool.chinaz.com/regex/进行在线测试
元字符:
. 匹配除换行符以外的任意字符
\w 匹配字母数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词的结尾
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W 匹配非字母或数字或下划线
\D 匹配非数字
\S 匹配非空白符
a|b 匹配字符a或字符b
( ) 匹配括号内的表达式,也表示一个组
[...] 匹配字符组的字符
[^...] 匹配除字符组中字符的所有字符
量词:
*重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n, } 重复n次或更多次
{n,m} 重复n到m次
贪婪匹配和惰性匹配
贪婪匹配: .* .+
惰性匹配: .*? 尽可能少的匹配
转义:
\\\\n => \\n => \n
在前面添加r,原样输出
分组: 使用()
在python中使用正则.re
<?P<name>正则>
re模块是python提供的一套关于处理正则表达式的模块,核心功能有四个:
findall() 查找所有,返回list
finditer() 查找返回,返回的是迭代器,
search() 搜索. 搜索到第一个结果返回
match() 匹配. 收到一个结果返回,从头开始匹配
compile( ) 编译
group('name') 获取数据
re.S 干掉 . 的换行
# re的工作是在python中执行正则表达式
import re
# find
result = re.findall("\d+", "baby的电话号是: 185123456789")
print(result) #['185123456789']
it = re.finditer("\d+", "baby123456789的电话号是: 185123456789")
for el in it:
print(el.group()) # 分组 #123456789
#185123456789
search 搜索, 查找
一旦匹配到结果. 直接返回, 如果匹配不到结果. 返回None
result = re.search("\d", "宝宝的电话是111")
print(result) #<_sre.SRE_Match object; span=(6, 7), match='1'>
print(result.group()) #1
匹配, 从头开始匹配. 相当于在你正则前面加了一个^
result = re.match("\d+", "157宝宝的电话是:")
print(result.group()) ###157
search和match的区别: search查找. 找到了结果就返回. match. 从头开始匹配.
# 坑: 爬虫的一个重点
# .*?
result = re.finditer(r"姓名:(?P<name>.*?), 爱好:(?P<hobby>.*?),", "姓名:宝宝, 爱好:女,")
for el in result:
print(el.group("name"), el.group("hobby"))
# 正则的常用操作
result = re.split("\d+", "宝宝110来找你了. 你回头收拾收拾去119报道")
print(result)
用正则替换
s = re.sub("\d+", "__sb__", "宝宝110来找你了. 你回头收拾收拾去119报道")
print(s)
s = re.subn("\d+", "__sb__", "宝宝110来找你了. 你回头收拾收拾去119报道") # 替换了xxx次
print(s)
code = "for i in range(10): print(i)"
c = compile(code, "", "exec") # 编译
exec(c) # 快速执行
reg = re.compile(r"\d+") # 编译了一段正则. 加载了一段正则
lst = reg.findall("呵呵, 宝宝才不去110呢.他要去120了")
print(lst)
re.findall(r"\d+", "呵呵, 宝宝才不去110呢.他要去120了")
lst = re.findall(r"a(?:\d+)c", "a123456c") # 把括号python中的分组变成了原来正则表达式中的分组
print(lst)
爬取电影天堂
# 爬取电影天堂
from urllib.request import urlopen
content = urlopen("https://www.dytt8.net/html/gndy/dyzz/20181219/57954.html").read().decode("gbk")
# print(content)
reg = r'<div id="Zoom">.*?片 名(?P<name>.*?)<br />◎年 代(?P<years>.*?)<br />.*?◎上映日期(?P<date>.*?)<br />'+ \
'.*?◎主 演(?P<main>.*?)◎简 介.*?<td style="WORD-WRAP: break-word" bgcolor="#fdfddf"><a href="(?P<download>.*?)">'
it = re.finditer(reg, content, re.S) # re.S 去掉.里面的\n
for el in it:
print(el.group("name"))
print(el.group("years"))
print(el.group("date"))
print(el.group("main").replace("<br /> ", ", "))
print(el.group("download"))