正则表达式、re模块
正则表达式简介
# 是一门独立的技术 所有编程都可以使用
它的作用可以简单的概括为:利用一些特殊符号(也可以直接需要查找的具体字符)的组合产生一特殊的含义然后去字符串中筛选出符合条件的数据 筛选数据(匹配数据)
是一个特殊的字符序列 它能帮助你方便的检查一个字符串是否与某种模式匹配
案列:京东注册手机号校验
基本需求:手机号必须是11位、手机号必须是以13 15 17 18 19 开头、必须是纯数字
while True:
phone = input('请输入您的手机号码>>>:').strip()
if len(phon) == 11:
if phone.isdigit():
if phon.startswith('13') or phone.startswith('15') or phone.startswith('17') or phone.startswith('18') or phone.startswith('19'):
print('手机号码正确')
else:
print('手机号码开头不对')
else:
print('手机号码必须是纯数字')
else:
print('手机号码必须是11位数字')
正则:
import re
phone = input('请输入您的手机号码')
if re,math('^(13|1415|18)[0-9]{9}$, phone'):
print('格式正确')
else:
print('格式错误')
字符组
# 字符组默认是匹配方式是挨个挨个匹配
[012356789] 匹配0到9任意一个数(全写)
[0-9] 匹配0到9任意一个数(缩写)
[a-z] 匹配26个小写英文字母
[A-Z] 匹配26个大写英文字母
[0-9a-zA-Z] 匹配数字或者小写字母或者大写字母
字符组内所有的数据默认都是或的关系
特殊符号
# 特殊符号默认是匹配方式是挨个挨个匹配
. 匹配除换行符以外的任意字符
\w 匹配数字、字母、下划线
\W 匹配非数字、非字母、非下划线
^ 匹配字符串的开头
$ 匹配字符串的结尾
两者者和使用可以非常精准的限制匹配的内容
a|b 匹配a或b(管道符的意思是或)
() 给正则表达式分组 不影响表达式的匹配功能
[] 字符组 内部填写的内容默认都是或的关系
[^] 取反操作 匹配除了字符组里面的其他所有字符(注意上尖号在中括号内和中括号外意识完全不同)
量词
# 正则表达式默认情况下都是贪婪匹配>>> 就是尽可能多的匹
* 匹配零次或多次 默认是多次(无穷次)
+ 匹配依次或多次 默认是多次(无穷次)
? 匹配零次或一次 作为量词意义不大主要用于非贪婪匹配
{n} 重复n次
{n,} 重复n次或更多次 默认是多次(无穷次)
{n, m} 重复n到m次 默认是m次
量词必须结合表达式一起使用 不能单独使用 并且只影响左边第一个表达式
如:
jason\d{3} 只影响\d
贪婪与非贪婪匹配
# 所用的量词都是贪婪匹配如果想变为非贪婪匹配只需要在量词后面加问号
待匹配的文本
<script>alret(123)</script>
待使用的正则(贪婪匹配)
<.*>
请问匹配的内容
<script>alert(123)</script> 一条
# .*属于典型的贪婪匹配 使用它 解释条件一般在左右明确指定
待使用的正则(非贪婪匹配)
<.*?>
转义符
# 斜杆与字母的组合有时候有特殊含义
\n 匹配的是换行符
\\n 匹配的是文本\n
\\\\n 匹配的是文本\\n
如果是在python中使用 还可以在字符串前面加r取消转义
正则表达式实战
# 能够写出简单的正则 能够大致看懂复杂的正则
1、编写校验用户身份证号的正则
^[1-9]\d{13,16}[0-9x]$
^[1-9]\d{14}(\d{2}[0-9x])?$
^([1-9]\d{16}[0-9x]|[1-9]\d{14})$
2、编写校验邮箱的正则
3、编写校验用户手机的正则(座机、移动)
4、编写校验用户qq号的正则
re模块
在python中如果想要使用正则 可以考虑re模块
import re
语法:findall(正则表达式,待匹配字符串)
说明:findall会匹配字符串中所有符合的字符 并且将其存在一个列表里返回
res = re.findall('a', 'jason apple eva')
print(res) # 查找符合正则表达式式要求的数据 结果是一个列表
说明:finditer跟findall只有一点不同,他不返回列表,而是返回一个迭代器对象
当待匹配的数据量很大时,考虑使用finditer =。=
res = re.finditer('a', 'jason apple eva')
print(res) # 查找所有符合正表达式要求的数据 结果直接是一个迭代器对象
说明:search匹配到一个符合条件的数据就立刻结束 如果没有匹配到返回None search方法执行完会生成一个Match对象
res = re.search('a', 'jason apple eva')
print(res) # <re.Match object; span=(1, 2), match='a'>
print(res.group()) # a 匹配到一个符合条件的数据就立刻结束
说明:从字符串的开头开始匹配 如果开头不匹配后面不用看了 直接结束返回None
res = re.match('a', 'jason apple eva')
print(res) # None 匹配字符串的开头 如果不符合后面就不用看了
print(res.group()) #匹配开头符合条件的数据 一个就结束
说明:当一个正则表达式需要重复使用 可以考虑使用compile将其做成模板
obj = re.compile('\d{3}') # 当某一个正则表达式需要频繁使用的时候 可以做成模板
res = obj.findall('42435q3535')
res1 = obj.findall('aafafea2346aga')
print(res, res1)
语法:re.sub(正则表达式, 替换成的字符串, 目标字符串, 替换的次数)
说明:sub用于删除或替换一长串字符中的某些部分 返回经过处理的字符串
ret = res.sub('\d', 'H', 'euhuahbf7fhushua9', 1) # 将数字替换成'H' 参数1表示只替换一个
print(ret) # euhuahbfHfhushua9
说明: 返回一个元祖 包含替换处理后的字符串 和 替换了几次(替换次数)
ret = re.subn('\d', 'H', 'eva3jason4yuan4') # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret) # ('evaHjasonHyuanH', 3)
ret = re.split('[ab]', 'abcd') # 先按'a'分割得到''和'bcd', 在对''和'bcd'分别按'b'分割
print(ret) # ['', '', 'cd']
re模块补充说明
1.分组优先
res = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(res) #['oldboy']
findall分组优先展示:优先展示括号内正则表达式匹配到的内容
res = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(res) # ['www.oldboy.com']
res = re,search('www.(baiduu|oldboy).com', 'www.oldboy.com')
print(res.group()) # www.oldboy.com
res = re.match('www.(baidu|oldboy).com', 'www.oldboy.com')
print(res.group()) # www.oldboy.com
2.分组别名
res = re.search('www.(?P<content>baidu|oldboy)(?P<hei>.com)', 'www,oldboy.com')
print(res.group()) # www.oldboy.com
print(res,group('content')) # oldboy
print(res.group(0)) # www.oldboy.com
print(res.group(1)) # oldboy
print(res.group(2)) # .com
print(res.group('hei')) # .com
网络爬虫简介
网络爬虫:通过代码编写模拟浏览器发送请求获取数据并按照自己指定的要求筛选出想要的数据
练习:
网络爬虫:通过编写代码模拟浏览器发送请求获取数据并按照自己指定的要求筛选出想要的数据
小练习:利用正则表达式筛选出红牛所有的分公司数据并打印或保存
公司名称:
公司地址:
公司邮编:
公司电话:
# http://www.redbull.com.cn/about/branch
import json
import re
with open("a.txt","r",encoding="utf8") as f:
res=f.read()
print(res)
my_format=re.compile("<h2>(?P<name>.*?)</h2><p class='mapIco'>(?P<address>.*?)</p><p class='mailIco'>(?P<mailIco>.*?)</p><p class='telIco'>(?P<telIco>.*?)</p>")
lt=my_format.findall(res)
print(lt)
# {
# "name":"红牛杭州分公司",
# "address":"杭州市上城区庆春路29号远洋大厦11楼A座",
# "mailIco":"310009",
# "telIco":"0571-87045279/7792",
# }
ft = ["name","address","mailIco","telIco"]
for data in lt:
message = {}
for i in range(len(ft)):
message[ft[i]]=data[i]
with open("b.txt","a",encoding="utf8") as f:
json.dump(message,f,ensure_ascii=False)
f.write("\n")
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!