Python高级-正则表达式
正则表达式的使用
一、匹配单个字符
| 字符 | 功能 |
|---|---|
| . | 匹配任意1个字符(除了\n) |
| [] | 匹配[ ]中列举的字符 |
| \d | 匹配数字,即0-9 |
| \D | 匹配⾮数字,即不是数字 |
| \s | 匹配空⽩,即 空格,\t-tab键 \n-换⾏ |
| \S | 匹配⾮空⽩ |
| \w | 匹配单词字符,即a-z、A-Z、0-9、_ |
| \W | 匹配⾮单词字符 |
-
.匹配任意单个字符(除\n) -
[]列举,匹配[]中列举的内容[ab]匹配 a 或者 b[a-z]匹配所有的小写字母[A-Z]匹配大写字母[0-9]匹配数字[a-zA-Z]匹配所有的小写字母和大写字母 -
\d匹配所有的数字 等价于[0-9] -
\D非数字 -
\s空格 -
\S非空格 -
\w匹配 字母、数字、下划线[a-zA-Z0-9_] -
\W非数字、非字母、非下划线
二、匹配多个字符
-
*表示前一个字符出现 0次或者 无限次 -
+表示 前一个字符出现 1次或者 无限次 -
?表示 前一个字符出现 0 次或者 1次 (要不不出现,要不只能出现一次) -
{m}表示前一个字符,连续出现 m次 -
{m,n}表示前一个字符,连续出现最少m次,最多n次
三、匹配开头结尾
-
^表示 匹配 以后一个字符开头^ 有两个作用:
1)匹配以 指定字符开头
^[a-zA-Z_]+\w # 必须以 小写字母、大写字母、下划线开头2)用在 [] 内部,用于取反
[^he] 匹配不含有 h 和 e 的字符 -
$表示匹配 以前一个字符结尾\d$ 以数字结尾
四、re模块操作
-
re模块的作用: python提供的用于正则操作的模块
-
re模块的使用步骤:
-
导入模块
import re
-
使用match() 方法进行检测
# 2、通过 match 方法,验证正则 # re.match("正则表达式", "要验证/检测的字符串") # match() 方法如果匹配成功,返回 match object 对象 # match() 方法如果匹配失败,返回 None # 正则字符串 要检测的内容 result = re.match("\w{4,20}@163\.com$", "hello@163.com") -
判断是否检测/匹配成功
if result: print("成功") else: print("失败") -
取出匹配的具体内容
result.group() 获取匹配的具体内容
-
五、匹配分组
| 字符 | 功能 |
|---|---|
| | | 匹配左右任意⼀个表达式 |
| (ab) | 将括号中字符作为⼀个分组 |
| \num | 引⽤分组num匹配到的字符串 |
| (?P) | 分组起别名 |
| (?P=name) | 引⽤别名为name分组匹配到的字符串 |
匹配分组之"|"
-
|的作用:或者关系,多个正则表达式满足任意一个都可以^[0-9]?[0-9]$|^100$ # ^[0-9]?[0-9]$ 满足或者 ^100$ 满足任意一个,返回值都是一个 match object 对象(匹配成功)
匹配分组之"()"
-
分组,整体匹配
result = re.match("\w{4,20}@(163|126|qq|sina)\.com$", "hello@126.com")把 @ .... ".com" 之间的内容整体进行匹配
-
提取子字符串
1 2
result = re.match("(\d{3,4})-(\d{7,8})", "010-12345678")`
result.group() 获取的是匹配的结果
result.group(1) 获取的是第一个括号中的内容
result.group(2) 获取的是第二个括号中的内容
匹配分组之‘\’
-
引用 分组
\1 表示引用第一组
# result = re.match("<([a-zA-Z0-9]+)>.*</\\1>", "<html>asdbasldfj</html>") result = re.match("<([a-zA-Z0-9]+)><([a-zA-Z0-9]+)>.*</\\2></\\1>", "<html><h1>asdbj</h1></html>")\\1表示引用第一组 ,\\是转义字符,转义后代表一个\\\2表示引用第二组 -
分组起别名
-
起名
?P
给分组起别名,别名为name1 -
引用别名
?P=name1 引用别名为 name1的分组
-
整体代码:
result = re.match("<(?P<name1>[a-zA-Z0-9]+)><(?P<name2>[a-zA-Z0-9]+)>.*</(?P=name2)></(?P=name1)>", "<html><h1>asdbj</h1></html>")
-
六、re模块的高级用法
-
search() 在需要匹配的字符串中搜索要匹配的内容
result = re.search("\d+", "阅读次数:9999")
知道 match 和 search的区别
# 1)match 从需要检测.group的字符串的开头位置匹配,如果失败返回 None # 2)search 从需要检测的字符串中搜索满足正则的内容,有则返回match object对象 -
findall() 在需要匹配的字符串中查找所有满足正则的内容,返回值是列表
result = re.findall("\d+", "阅读次数:9999,转发次数:6666,评论次数:38")
-
sub("正则表达式", "新的内容", "要替换的字符串") 字符串替换(按照正则,查找字符串并且替换为指定的内容)返回值是替换后的字符串
result = re.sub("\d+", "10000", "阅读次数:9999,转发次数:6666,评论次数:38")
-
split("正则表达式", "待拆分的字符串") 按照正则拆分字符串,返回值是一个列表
result = re.split("😐 ", "info:hello@163.com zhangsan lisi")
七、贪婪和非贪婪
- 贪婪:默认,表示在满足正则的情况尽可能多的取内容
- 非贪婪:表示在满足正则的情况下,尽可能少的取内容
- 贪婪的转变为非贪婪: 在 * ? + {} 的后面再加上 ?就可以了
result = re.match("aaa(\d+?)", "aaa123456")
八、r的作用
- r的作用: 让正则中的 \ 表示原生的含义,仅仅对
\起作用
九、案例:《简单爬虫-批量获取电影下载链接》
-
思路:
一、定义函数获取列表页的内容页地址 get_movie_links()
1、定义列表的地址 http://www.ygdy8.net/html/gndy/dyzz/list_23_1.html
2、打开url地址,获取数据
3、解码获取到的数据
4、使用正则得到所有的影片内容也地址 4.1 遍历,取出内容页地址
4.2 拼接内容页地址
4.3 打开内容页地址
4.4 获取数据,并读取
4.5 解码内容页数据,得到html内容页文本
4.6 使用正则,获取下载地址的连接
4.7 把影片信息和下载链接,保存到字典中
4.8 返回字典
二、主函数 main
1、调用 get_movie_lisgt() ,得到字典
2、遍历字典,显示下载的内容
-
代码
""" https://www.dytt8.net/ 一.定义函数,获取列表页的内容页地址get_movie_links() 1.定义列表页的地址:https://www.dytt8.net/html/gndy/dyzz/list_23_1.html 2.打开url地址,获取数据 3.解码获取到的数据 4.使用正则得到所有影片内容页地址 二.主函数main() """ import urllib.request import re def get_movie_links(): """获取列表页的内容页地址""" film_list_url = "https://www.dytt8.net/html/gndy/dyzz/list_23_1.html" res_list = urllib.request.urlopen(film_list_url) # print(res_list) # ----> <http.client.HTTPResponse object at 0x7f0e656e2370> res_list_data = res_list.read() # print(res_list_data) # ----> 二进制格式 # <META http-equiv=Content-Type content="text/html; charset=gb2312"> res_list_text = res_list_data.decode("GBK") # print(res_list_text) # ----> 网页源代码 url_list = re.findall(r"<a href=\"(.*)\" class=\"ulink\">(.*)</a>", res_list_text) # url_list = [("地址", "影片"), (), ...] # print(url_list) film_dict = {} i = 0 for content_url, film_name in url_list: content_url = "https://www.dytt8.net" + content_url # print(f"影片名称:{film_name},内容页地址:{content_url}") # 打开内容页地址 res_content = urllib.request.urlopen(content_url) res_content_data = res_content.read() res_content_text = res_content_data.decode("GBK") result = re.search(r"(magnet:.*?)\"", res_content_text) film_url = result.group(1) # print(film_url) # 组装字典 film_dict[film_name] = film_url i += 1 print(f"已获取第{i}部电影:【{film_name}】的下载地址") return film_dict def main(): film_down = get_movie_links() # print(film_down) print() for filmname, filmlink in film_down.items(): print(f"电影名称:\n{filmname}\n下载地址:\n{filmlink}\n\n") if __name__ == '__main__': main()
浙公网安备 33010602011771号