此博客用于个人学习,是看大佬的视频做的笔记,侵权可联系本人删除 ~~
可用RegexBuddy工具验证
匹配单个字符
字符 | 功能 |
---|---|
. | 匹配任意1个字符(除了\n |
[] | 匹配[ ]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字,即不是数字 |
\s | 匹配空白,即空格,\t-tab键 \n-换行 |
\S | 匹配非空白 |
\w | 匹配单词字符,即a-z、A-Z、0-9、_ |
\W | 匹配非单词字符 |
匹配多个字符
字符 | 功能 |
---|---|
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现1次或者无限次,即至少有1次 |
? | 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 |
{m} | 匹配前一个字符出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
示例1:*
需求:匹配出一个字符串第一个字母为大写字母,后面都是小写字母且这些小写字母可有可无
[A-Z][a-z]*
*修饰了前面的[a-z],表示可以有0个或多个小写字母
示例2:+
需求:匹配出变量名是否有效
[A-Za-z_]+\w
示例3:?
需求:匹配出0到99之间的数字
[0-9]?[0-9]
示例4:{m} – 匹配前一个字符出现m次
需求:不是以4、7结尾的手机号码(11位)
\d{10}[12356890]
或者\d{10}[0-35-68-9]
示例4:{n,m} ---- n< m
需求:匹配出8到20位的密码,可以是大小写英文字母,数字,下划线
\w{8,20}
练一练
题目1:匹配出163的邮箱地址,且@符号之前有4到20位,例如hello@163.com
\w{4,20}@163.com -- 因为.有特殊含义,表示任意字符,所以加个\转义
\w{4,20}@163\.com$
字符 | 功能 |
---|---|
^ | 匹配字符串开头,注意1和[ ^4-7]的区别 |
$ | 匹配字符串结尾 |
2 — 以4-7数字开头
[ ^4-7] — 不包含4-7的数字
^[a-zA-Z0-9_]+\w 以数字、字母、下划线开头的任意字符
需求:以数字结尾:
.*\d$
匹配分组|
字符 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
(ab) | 将括号中字符作为一个分组 |
\num | 引用分组num匹配到的字符串 |
(?P) | 分组起别名 |
(?P=name) | 引用别名为name分组匹配到的字符串 |
字符:|
需求:匹配0-100
^[0-9]?[0-9]$|^100$
字符:()
括号里面内容进行整体匹配
# 1、导入模块
import re
# 2、match()进行匹配
# result = re.match('\w{4,20}@(163|126|qq)\.com','hello@163.com')
result = re.match('(\d{3,4})-(\d{7,8})','010-12345678')
# 3、判断匹配的结果
if result:
print('匹配成功!')
# 4、取出匹配的内容
print(result.group())
# 在group中放入数字,表示取第几个括号中可匹配的子字符串
print('区号为:',result.group(1))
print('电话号码为:',result.group(2))
else:
print('匹配失败')
匹配分组之\
\1表示引用第一组
# </\\1>的两个\是为了转义成一个\
# \\1表示引用第一个分组 ,\\2表示引用第二个分组
# result = re.match('<([a-zA-Z0-9]+)>.*</\\1>', '<html>testjkjio</html>')
result = re.match('<([a-zA-Z0-9]+)><([a-zA-Z0-9]+)>.*</\\2></\\1>', '<html><h1>testjkjio</h1></html>')
分组起别名:
# ?P<name1> 给分组起别名,别名为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>testjkjio</h1></html>')
re模块的高级用法:
- search() 在需要匹配的字符串中搜索要匹配的内容
'''
match和search的区别:
1、match从需要检测字符串的开头位置匹配,如果失败返回None
2、search从需要检测的字符串中搜索满足正则的内容,有则返回match object对象
'''
# 一、search的使用
# result = re.search('hello', 'xhello@163.com')
- findall(“正则表达式”,“待查找的内容”) 搜索全部,返回值是个列表
# result = re.findall("\d+","阅读次数:999,转发次数:565,评论次数:12")
- sub(“正则表达式”, “新的内容”, “要替换的字符串”) 字符串替换(按照正则,查找字符串并且替换为指定的内容)
# 返回值是替换后的字符串
# result = re.sub("\d+","1000", "阅读次数:999,转发次数:565,评论次数:12")
- split(“正则表达式”, “待拆分的字符串”) 按照正则拆分字符串,返回值是一个列表
result = re.split(':| ','info:hello@163.com makabaka wuxidixi')
python贪婪和非贪婪
- 知道贪婪匹配的特点
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪), 总是尝试匹配尽可能多的字符;
非贪婪则相反,总是尝试匹配尽可能少的字符。
在",“?”,“+”,{m,n}"后面加上?, 使贪婪变成非贪婪。
str1 = '<link href="//js.51jobcdn.com/in/resource/css/2021/jobs/jobDetail.02a97aa2.css" rel="stylesheet">'
result = re.search('href=\"(.*?)"',str1)
r的作用
让正则的 \ 表示原生的含义,仅仅对\起作用,即正则加了r可以不使用\\转义
# r的含义是让正则中的 \ 没有特殊含义,就是代表原生的\
# 但是r只能对\起作用,如果正则有.的话还是需要用\.才行
result = re.match(r'<([a-zA-Z0-9]+)><([a-zA-Z0-9]+)>.*</\2></\1>', '<html><h1>testjkjio</h1></html>')
9.14 【应用】案例:《简单爬虫-批量获取电影下载链接》
'''
一、定义函数获取列表页的内容页地址 get_movie_links
1、定义列表的地址
2、打开url地址,获取数据
3、解码获取到的数据
4、使用正则得到所有影片内容的地址
二、
'''
import urllib.request
import re
def get_movie_links():
'''获取列表页影片信息'''
# 1、定义列表的地址
url = 'https://www.自己找一个可用的网站即可.net/index.html'
# 2、打开url地址,获取数据
url_datas = urllib.request.urlopen(url)
# 2.1、通过read()读取网络资源数据
movie_list = url_datas.read()
# 3、解码获取到的数据
movie_data = movie_list.decode('GBK')
# 4、使用正则得到所有影片内容的地址
# 4.1、使用findall()根据正则查找所有影片对应的内容页地址
url_lists = re.findall(r'<a href=\"(.*?)\" class=\"ulink\">(.*?)</a>',movie_data)
# 4.2、保存地址
# print(url_lists)
# 定义一个字典,用于保存影片信息
films_dict = {}
# 4.3 循环遍历url_list
i = 1
for cont_url,file_name in url_lists:
# 拼接内容页地址
cont_url = 'https://www.XXXX.net' + cont_url
# print(f"影片名称:{cont_url} ; 内容页地址:{file_name}")
# 4.4 打开内容页地址
content_address = urllib.request.urlopen(cont_url)
# 4.5 接收内容页数据
# 4.6 读取网络资源
content_datas = content_address.read()
# 4.7 解码得到内容页的文本内容
content_text = content_datas.decode('GBK')
# 4.8 取出下载地址
imgs = re.search(r'<img border=\"0\" src=\"(.*?)\" alt=\"\" style=\"MAX-WIDTH: 400px\" />',content_text)
# 字典
# {"xxx影片": "影片图片"}
films_dict[file_name] = imgs.group(1)
print(f'已获取{i}条图片地址信息')
i += 1
return films_dict
def main():
films_dict = get_movie_links()
# print(films_dict)
# 把字典遍历输出
for k,v in films_dict:
print(f"{k} | {v}")
if __name__ == '__main__':
main()