Python进阶系列
Python进阶-网络编程-01
Python进阶-网络编程-02
Python进阶-网络编程-03
Python进阶-多任务编程-01
Python进阶-多任务编程-02
Python进阶-多任务编程-03
Python进阶-正则表达式
Python进阶-数据库编程-01
Python进阶-数据库编程-02
Python进阶-数据库编程-03
Python进阶-数据库编程-04
Python进阶-数据拷贝问题
Python进阶-模块导入问题
Python进阶-miniWeb框架
文章目录
9.1. 正则表达式概述
- 正则表达式概念:规则表达式(一套特殊的规则)
- 正则表达式的作用:
- 验证数据的有效性(查找)
- 替换文本内容
- 从字符串中提取子字符串(爬虫思想)
9.2. 测试工具介绍
- regexBuddy :用来测试正则表达式的正确性
- 使用:
-
选择 python3.6
-
点击test选项卡
-
9.3. 匹配单个字符
9.4. 匹配多个字符
9.5. 匹配开头结尾
-
^
表示匹配以后一个字符开头# 必须以小写字母、大写字母、下划线开头 ^[a-zA-Z_]+\w
用在
[]
内部,用于取反# 匹配不含有 h 和 e 的字符 [^he]
-
$
表示匹配以前一个字符结尾# 以数字结尾 \d$
9.6. re模块操作
-
re模块的作用:python提供的用于正则操作的模块
-
re
模块的使用步骤:-
导入模块
import re
-
使用
match()
方法进行检测# 2、通过match方法,验证正则 # re.match("正则表达式","要验证/检测的字符串") # match()方法如果匹配成功,返回match object对象 # match()方法如果匹配失败,返回None 正则字符串 要检测的内容 result re.match("\w{4,20}@163\.coms","hello@163.com")
-
判断是否检测/匹配成功
if result: print("匹配成功") else: print("匹配失败")
-
取出匹配的具体内容
result.group()
-
-
代码实例:
# 1.导入模块 import re # 2.使用match()方法进行检测 result = re.match("\w{4,20}@163\.com$","hello@163.com") # 3.判断是否检测/匹配成功 if result: print("匹配成功") else: print("匹配失败") # 4.取出匹配的具体内容 print("匹配结果:",result.group())
9.7. 匹配分组之"|"
-
|
的作用:或者关系,多个正则表达式满足其中一个即可# 引号内部不能出现非匹配的任何字符 # 判断0-100之间的数字 "^[0-9]?[0-9]$|^100$"
-
代码实例:
import re result = re.match("^[0-9]?[0-9]$|^100$","13") if result: print("匹配成功") else: print("匹配失败") print("匹配结果:",result.group())
9.8. 匹配分组之"()"
-
分组,整体匹配
result = re.match("\w{4,20}@(163|126|qq|sina)\.com$","hello@qq.com")
-
提取子字符串
result = re.match("(\d{3,4})-(\d{7,8})","010-12345657") result.group() # 获取匹配的结果 result.group(1) # 获取第一个括号中的内容 result.group(2) # 获取第二个括号中的内容
-
代码实例:
import re result = re.match("(\d{3,4})-(\d{7,8})","010-12345657") if result: print("匹配成功") print("匹配的结果:",result.group()) print("提取区号:",result.group(1)) print("提取电话号码:",result.group(2)) else: print("匹配失败")
9.9. 匹配分组之""
-
引用分组
\1
表示引用第一组result = re.match("<([a-zA-Z0-9]+)>.*</\\1>","<html>test</html>") result = re.match("<([a-zA-Z0-9]+)><([a-zA-Z0-9]+)>.*</\\2></\\1>","<html><h1>test</h1></html>")
\\1
表示引用第一组,\\
是转义字符,转义后代表一个\
\\2
表示引用第二组 -
代码实例:
import re result = re.match("<([a-zA-Z0-9]+)><([a-zA-Z0-9]+)>.*</\\2></\\1>","<html><h1>test</h1></html>") if result: print("匹配成功") else: print("匹配失败") print("匹配结果:",result.group())
-
分组起别名
-
起名:
?P<name>
给分组起别名,别名为name
-
引用别名:
(?P=name)
引用别名为name
的分组 -
代码实例:
import re result = re.match("<(?P<name1>[a-zA-Z0-9]+)><(?P<name2>[a-zA-Z0-9]+)>.*</(?P=name2)></(?P=name1)>","<html><h1>test</h1></html>") if result: print("匹配成功") else: print("匹配失败") print("匹配结果:",result.group())
-
9.10. re模块的高级用法
-
search()
在需要匹配的字符串中搜索要匹配的内容# result=re.search("正则表达式","要搜索的内容") result=re.search("\d+","阅次数:9999")
- 知道
match
和search
的区别- match从需要检测.group的字符串的开头位置匹配,如果失败返回None
- search从需要检测的字符串中搜索满足正则的内容,有则返回match object对象
- 知道
-
findall()
在需要匹配的字符串中查找所有满足正则的内容,返回值是列表# result = re.findall("正则表达式","要搜索的内容s") result = re.findall("\d+","阅读次数:9999,转发次数:6666,评论次数:38")
-
sub()
# sub("正则表达式","新的内容","要替换的字符串") # 将阅读次数,转发次数,评论次数都改为10000 result = re.sub("\d+","10000","阅读次数:9999,转发次数:6666,评论次数:38")
-
split()
# split("正则表达式”,"待拆分的字符串") # 以 ":" 或者 " " 拆分字符串 result = re.split(":| ","info:hello@162.com zhangsan lisi")
9.11. 贪婪和非贪婪
-
贪婪:满足正则的规则下,尽可能多的取内容
-
非贪婪:满足正则的情况下,尽可能少的取内容
-
把贪婪模式改为非贪婪模式,在
* ? + {}
后面加上?
-
代码实例:
import re str1 = """ 1131917_sma11,jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917 small.jpg" style="display:inline;"> """ result = re.search("src=\"(.*?)\"",str1) if result: print("匹配成功") print("地址:",result.group(1)) else: print("匹配失败") print("匹配结果:",result.group())
9.12. r的作用
-
r
的作用:让正则中的\
表示原生的含义,仅仅对\
起作用 -
代码实例:
import re result = re.match(r"<([a-zA-Z0-9]+)><([a-zA-Z0-9]+)>.*</\2></\1>","<html><h1>test</h1></html>") if result: print("匹配成功") else: print("匹配失败") print("匹配结果:",result.group())
9.13. 案例:《简单爬虫-批量获取电影下载链接》
-
定义函数获取列表页的内容页地址
get_movie_links()
-
定义列表页的地址
https://www.ygdy8.net/html/gndy/dyzz/index.html
-
打开url地址,获取数据
-
解码获取到的数据
-
使用正则得到所有的影片内容页地址
4.1 遍历,取出内容页地址 4.2 拼接内容页地址 4.3 打开内容页地址 4.4 获取数据,并读取 4.5 解码内容页数据,获取html内容页文本 4.6 使用正则,获取下载地址的连接 4.7 把影片信息和下载链接,保存到字典中
4.8 返回字典
-
-
主函数
- 调用
get_movie_links()
,得到字典 - 遍历字典,显示下载内容
- 调用
-
代码实例:
import urllib.request import re def main(): films_dict = get_movie_links() # print(films_dict) # 把字典遍历输出 for file_name,file_link in films_dict.items(): print("%s | %s" % (file_name,file_link)) def get_movie_links(): """获取列表页影片信息""" # 1.定义列表页的地址 https://www.ygdy8.net/html/gndy/dyzz/index.html file_list_url = "https://www.ygdy8.net/html/gndy/dyzz/list_23_1.html" # 2.打开url地址,获取数据 response_list = urllib.request.urlopen(file_list_url) # 通过read()读取网络资源数据 response_list_data = response_list.read() # 3.解码获取到的数据 response_list_text = response_list_data.decode("GBK") # 4.使用正则得到所有的影片内容页地址 # print(response_list_text) # 4.1 使用findall() 根据正则查找所用影片对应的内容页地址 # 返回的数据是个大列表,列表元素为元组,第一个元素是页面的url地址,第二个元素是影片名 称 url_list = re.findall(r"<a href=\"(.*)\" class=\"ulink\">(.*) </a>",response_list_text) # 4.2 保存地址 # 定义一个字典用于保存影片信息 films_dict = {} i=1 # 4.3 循环遍历 url_list for content_url,file_name in url_list: content_url = "https://www.ygdy8.net" + content_url print("影片名称:%s, 内容页地址:%s" % (file_name,content_url)) # 4.4 打开内容页地址 response_content = urllib.request.urlopen(content_url) # 4.5 接收内容页数据 # 4.6 读取网络资源 response_content_data = response_content.read() # 4.7 解码得到内容页的文本内容 response_content_text = response_content_data.decode("GBK") # 4.8 取出下载地址 # print(response_content_text) result = re.search(r"magnet:\?xt=urn:btih: (.*)fannounce",response_content_text) # print("下载地址%d:" % i,result.group()) # 字典 # {"xxx":"XXX地址"} films_dict[file_name] = result.group() print("已经获取%d条信息" % i) i += 1 return films_dict if __name__ == '__main__': main()