day17正则表达式
一、OS的补充
- 创建文件夹 :在指定位置创建指定文件夹
os.mkdir('files/test')
#如果文件夹存在,会报错
- 判断指定文件夹或者文件是否存在
os.path.exists('文件夹或者文件路径')
- 正确的创建文件或者文件夹方式
if not os.path.exists('files/test'):
os.mkdir('files/test')
二、正则表达式的作用
-
正则表达式是一种可以让复杂的字符串问题变得简单的工具
-
写正则表达式的时候是用正则符号来描述字符串规则
-
案例:判断一个字符串是否是一个合法的手机号码
import re
tel=''
result=re.fullmatch(r'1[3-9]\d{9}',tel)
三、常用函数
1、re模块
- 提供了python中所有相关的正则函数
2、常用函数
-
1)、fullmatch(正则表达式,字符串)
- 判断整个字符串是否满足正则表达式所描述的规则
- 匹配成功返回匹配对象,失败返回None
-
2)、findall(正则表达式,字符串)
- 提取字符串中所有满足正则表达式的子串
- 默认情况下返回一个列表,列表中的元素是所有匹配到的子串
- 存在自动捕获匹配现象
-
3)、search(正则表达式,字符串)
- 查找字符串中第一个满足正则表达式的字符串
- 匹配成功返回匹配对象,失败返回None
-
4)、split(正则表达式,字符串,[N])
- 将字符串中所有满足正则的前N个子串作为切割点进行切割
-
5)、sub(正则表达式,字符串1,字符串2, [N])
- 将字符串2中所有满足正则的子串的替换成字符串1
-
6)、finditer(正则表达式,字符串)
- 获取字符串中所有满足正则的子串,
- 返回一个迭代器,迭代器的元素是匹配对象
-
7)、match(正则表达式,字符串)
- 匹配字符串开头
四、第一类符号:匹配字符
1、正则符号
1) 普通符号 - 在正则表达式中表示符号本身的符号
result=fullmatch(r'abc','abc') # 正则表达式中要求字符串第一个字符是a第二个字符是b第三个字符数c
result=fullmatch(r'abc','abo') # 不匹配 None
2) . - 匹配任意字符
result=fullmatch(r'.bc','abc')
print(result) # <re.Match object; span=(0, 3), match='abc'>
3) \d - 匹配任意一个数字字符
result=fullmatch(r'\d\dabc','14abc')
print(result)
4) \s - 匹配任意一个空白字符
- 空白字符:空格(’ ')、换行(\n)、水平制表符(\t)
result=fullmatch(r'123\sabc','123\tabc')
print(result)
5) \w - 匹配任意一个数字、字母、下划线、中文
result=fullmatch(r'123\w','123中')
print(result) # <re.Match object; span=(0, 4), match='123中'>
result=fullmatch(r'123\w','123*')
print(result) # None
6) \D、\S、\W - 分别和\d \s \w的功能相反
result=fullmatch(r'abc\Dabc','abc3abc')
print(result) # None
result=fullmatch(r'abc\Dabc','abc和abc')
print(result)
7) [字符集] - 匹配在字符集中的任意一个字符
- [abc] - 匹配a或者b或者c
- [abc\d] - 匹配a或者b或者c或者数字 等价于[abc1234567890]
- [[1-8] - 匹配字符1到字符8中的任意一个字符
- [a-z] - 匹配任意一个小写字母
- [a-zA-Z] - 匹配任意字母字符
- [a-zA-Z\d] - 匹配任意字母字符或者数字
- [\u4e00-\u9fa5] - 匹配任意一个中文
result=fullmatch(r'abc[m9你]abc','abcmabc')
print(result) # <re.Match object; span=(0, 7), match='abcmabc'>
result=fullmatch(r'abc[m9你]abc','abc0abc')
print(result) # None
8) [ ^ 字符集 ] - 匹配不在字符集中的任意字符
- ^只有放在[]的·开头才有效,放在字符中间失效
result=fullmatch(r'abc[^123]abc','abc1abc')
print(result) # None
五、第二类符号:匹配次数符号
匹配类符号匹配次数符号
1) * - 连续任意次数
- a* - a出现任意次数
- \d* - 任意多个任意数字
- [abc]* - 任意多个abc
result=fullmatch(r'abc\d*abc','abc12abc')
print(result)
2) + - 连续一次或者多次(至少一次)
result=fullmatch(r'abc\d+abc','abc12abc')
print(result)
3) ? - 连续0次或者1次
result=fullmatch(r'abc\d?abc','abc12abc')
print(result) # None
4) {}
- {N} - N次
- {M,N} - M到N次
- {M,} - 至少M次
- {,N} - 最大N次
result=fullmatch(r'abc\d{3,9}abc','abc12abc')
print(result) # None
- 练习1:写一个正则表达式可以匹配任意一个除了0的整数
result=fullmatch(r'[-+]?[1-9]\d*','400')
print(result)
- 练习2:使用正则提取豆瓣top250中每个电影的详情地址
url='https://movie.douban.com/top250'
import requests
from re import findall
header= {
'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36'
}
response=requests.get(url,headers=header)
result=response.text
result_1=findall(r'<a href="(https://movie.douban.com/subject/.+?/)" class="">',response.text)
# 写入大部分要求的字符串,得到的结果更准确
print(result_1)
六、第三类符号:分组和分支符号
1) 分组 - ()
- 正则表达式中可以用()将部分内容括起来表示一个整体。括号括起来的一个部分就是一个分组
- a. 整体操作时候需要分组
- b. 重复匹配 - 在正则中可以通过\M来重复前面第M个分组匹配的结果
- c. 捕获 - 提取分组匹配的结果(捕获分为自动捕获和手动捕获)
findall是自动捕获
# a. 整体操作时候需要分组
# 23M 10K23K90G
result=fullmatch(r'(\d\d[A-Z])+','12S')
# b. 重复匹配 - 在正则中可以通过\M来重复前面第M个分组匹配的结果
# 90M90 10M10
result=fullmatch(r'(\d\d)[A-Z]\1','13K13')
result=fullmatch(r'(abc)([1-9]{2})\2\1','abc1212abc')
print(result) # <re.Match object; span=(0, 10), match='abc1212abc'>
result=fullmatch(r'(abc)\1([1-9]{2})\2','abcabc1212')
print(result) # <re.Match object; span=(0, 10), match='abcabc1212'>
c. 捕获
- findall在正则表达式中有分组的时候,会自动提取正则匹配结果中分组匹配到的内容
# c. 捕获
# findall在正则表达式中有分组的时候,会自动提取正则匹配结果中分组匹配到的内容
msg='拟合123hg453=哈哈90'
result=findall(r'[\u4e00-\u9fa5](\d+)',msg)
print(result)
- 匹配对象.gruop(N) - 手动获取匹配结果中指定分组匹配到的内容
# 提取身高
msg='年龄14,身高168cm'
result=search(r'年龄(\d+),身高(\d+)',msg)
print(result.group(1),result.group(2))
2) 分支
- 正则1|正则2|正则3…先用正则1匹配,失败则用正则2匹配,…三给表达式中有一个匹配成功,结果就成功
result = fullmatch(r'\d{3}|[a-z]{2}', 'ab')
print(result) # <re.Match object; span=(0, 2), match='ab'>
- 案例:‘abcZB’ ‘abc12’ ‘abc20’
result = fullmatch(r'abc\d{2}|abc[A-Z]{2}', 'abcZB')
print(result)
# 优化
result = fullmatch(r'abc(\d{2}|[A-Z]{2})', 'abcZB')
print(result) # <re.Match object; span=(0, 5), match='abcZB'>
七、第四类符号:转义字符
-
**转义字符:**在本身具有特殊功能或者特殊意义的符号前加 \ ,让特殊符号变成普通符号
-
**注意:**单独存在有特殊意义的符号,在[]中它的功能会自动消失
[]里面如果有[]需要在[]前加 \
result = fullmatch(r'\d\+\d', '4+6')
print(result) # <re.Match object; span=(0, 3), match='4+6'>
result = fullmatch(r'\d[+]\d', '4+6')
print(result) # <re.Match object; span=(0, 3), match='4+6'>
- **案例:**匹配小数23.56 96.3
result = fullmatch(r'[1-9]\d*[.]\d*', '322.0')
print(result) # <re.Match object; span=(0, 5), match='322.0'>
八、补充
1、忽略大小写:r’(?i)正则表达式’
print(fullmatch(r'(?i)abc','Abc')) # <re.Match object; span=(0, 3), match='Abc'>
2、单行匹配:(?s)
多行匹配(默认):. 不能和换行符匹配
区别:单行匹配时可以和换行符进行匹配
print(fullmatch(r'abc.123','abc\n123')) # None
print(fullmatch(r'(?s)abc.123','abc\n123')) # <re.Match object; span=(0, 7), match='abc\n123'>