day2023-3-28-正则表达式
Posted summer--alian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了day2023-3-28-正则表达式相关的知识,希望对你有一定的参考价值。
补充:os模块
import os
# os.mkdir(文件路径) —— 在指定的位置创建指定文件夹
# os.mkdir('files/test')
# os.path.exists(文件夹路径/文件路径) —— 判断指定文件夹或者文件是否存在
if not os.path.exists('files/test'):
os.mkdir('files/test')
一、正则表达式
1.正则的作用
正则表达式是一种可以让复杂的字符串变得简单的工具;
写正则表达式就是用正则符号来描述字符串应该满足的规则。
import re
from re import *
# 案例1:判断一个字符串是否是手机号
tel = 15775898786
result = re.fullmatch(r'1[3-9]\\d9', tel)
if result:
print('合法')
else:
print('不合法')
# 案例2:提取字符串中所有的数字子串,并且求和
str1 = 'jisunf78-=3.67会议激素19'
result = re.findall(r'\\d+\\.?\\d*', str1)
print(sum([float(x) for x in result]))
二、正则语法
1.第一类符号:匹配类符号
1)普通符号 —— 在正则表达式中表示符号本身的符号
from re import fullmatch, findall, search
result = fullmatch(r'abc', 'abc')
print(result)
2).
—— 匹配任意一个字符
result = fullmatch(r'.bc', ';bc')
print(result)
result = fullmatch(r'.bc.', '2bcd')
print(result)
3)\\d
—— 匹配任意一个数字字符
result = fullmatch(r'\\d\\dabc', '72abc')
print(result)
4)\\s
—— 匹配任意一个空白字符
空白字符:空格(’ ‘)、换行(’\\n’)、水平制表符(‘\\t’)
result = fullmatch(r'123\\sabc', '123\\nabc')
print(result)
result = fullmatch(r'\\d\\d\\s\\d', '89 1')
print(result)
5)\\w
—— 匹配任意一个字母、数字、下划线或者中文
result = fullmatch(r'abc\\w123', 'abc_123')
print(result)
6)\\D
、\\S
、\\W
—— 分别和\\d、\\s、\\w的功能相反
# \\D —— 匹配任意一个非数字字符
result = fullmatch(r'abc\\D123', 'abcj123')
print(result)
# \\S —— 匹配任意一个非空白字符
result = fullmatch(r'abc\\S123', 'abc-123')
print(result)
# \\W —— 匹配任意一个 非 字母、数字、下划线或者中文
result = fullmatch(r'abc\\W123', 'abc+123')
print(result)
7)[字符集]
—— 匹配在字符集中的任意一个字符
"""
[abc] —— 匹配a,b,c
[abc\\d] —— 匹配a,b,c,任意数字:[abc0123456789]
[1-5] —— 匹配字符1到字符5中的任意一个字符
[a-z] —— 匹配任意一个小写字母
[A-Z] —— 匹配任意一个大写字母
[a-zA-Z] —— 匹配任意一个字母
[a-zA-Z\\d] —— 匹配任意一个字母或者数字
[a-z=%] ——
[\\u4e00-\\u9fa5] —— 匹配任意一个中文
"""
result = fullmatch(r'abc[M9你\\d]123', 'abc0123')
print(result)
result = fullmatch(r'abc[\\u4e00-\\u9fa5]123', 'abc胡123')
print(result)
8)[^字符串]
—— 匹配不在字符集中的任意一个字符
result = fullmatch(r'abc[^MN]123', 'abcl123')
print(result)
result = fullmatch(r'abc[^a-z]123', 'abcl123')
print(result) # None
2.第二类符号:匹配次数符号
匹配类符号匹配次数
1)*
—— 任意次数(0次或者1次或者次数)
"""
a* —— a出现任意多次
\\d* —— 任意多个任意数字
[abc]*
"""
result = fullmatch(r'1a*2', '1aaaaaaaaaaaa2')
print(result)
result = fullmatch(r'M\\d*2', 'M123452')
print(result)
result = fullmatch(r'M[3-9]*2', 'M3452')
print(result)
2)+
—— 一次或者多次(至少一次)
result = fullmatch(r'1a+2', '12')
print(result) # None
3)?
—— 0次或者1次
result = fullmatch(r'1a?2', '1aa2')
print(result) # None
4)
"""
N —— N次
M,N —— M到N次
M, —— 至少M次
,N —— 最多N次
"""
result = fullmatch(r'1a32', '1aa2')
print(result) # None
result = fullmatch(r'1a3,62', '1aaaa2')
print(result)
result = fullmatch(r'\\d3', '123')
print(result) # <re.Match object; span=(0, 3), match='123'>
# 练习:写一个正则表达式,可以匹配任意一个除了0的整数。
# 合法:233、+234、-7283、100、-2000
# 不合法:0、0002、2.23
result = fullmatch(r'[+-]?[1-9]\\d*', '-1023')
print(result)
5)贪婪和非贪婪模式
在匹配次数不确定的时候,如果有多种次数都可以匹配成功,贪婪取最多的那个次数,非贪婪取最少的那个次数。
贪婪模式:+、?、、M,N、M,、,N
非贪婪模式:+?、??、?、M,N?、M,?、,N?
# 'ahkmb','ahkmb首饰b','ahkmb首饰b奇数b'
result =search(r'a.+b', 'ahkmb首饰b奇数b')
print(result) # <re.Match object; span=(0, 11), match='ahkmb首饰b奇数b'>
result =search(r'a.+?b', 'ahkmb首饰b奇数b')
print(result) # <re.Match object; span=(0, 5), match='ahkmb'>
3.第三类符号:分组和分支
1)分组 —— ()
正则表达式中可以用()将部分内容括起来表示一个整体。括号括起来的部分就是一个分组。
a.整体操作的时候需要分组
b.重复匹配 —— 正则中可以通过\\M来重复它前面第M个分组匹配的结果
c.捕获 —— 提取分组匹配到的结果(捕获分为自动捕获(findall)和手动捕获)
# '23M'、'89K23L'、'67C34D73Y29S',...
result = fullmatch(r'(\\d\\d[A-Z])+', '67C34D73Y29S')
print(result)
# '23M23','90K90','34f34'
result = fullmatch(r'(\\d\\d)[A-Z]\\1', '23M23')
print(result)
result = fullmatch(r'(\\d\\d2)([a-z]4)=\\2\\12', '233dddd=dddd233233')
print(result)
findall在正则表达式中有分组的时候,会自动提取正则匹配结果中分组匹配到的内容
message = '奇数偶数234jiushe897dhue-=2398'
result = findall(r'[\\u4e00-\\u9fa5](\\d+)', message)
print(result)
# 提取身高
message = '我是小明,今年23岁,身高180厘米,体重70kg'
result = search(r'身高(\\d+)厘米,体重(\\d+)kg', message)
匹配对象.group(N) —— 获取匹配结果中指定分组匹配到的内容
print(result) # <re.Match object; span=(11, 25), match='身高180厘米,体重70kg'>
print(result.group()) # 身高180厘米,体重70kg
print(result.group(1), result.group(2)) # 180 70
2)分支 —— |
正则1|正则2|正则3|… —— 先用正则1进行匹配,匹配成功直接成功;匹配失败用正则2进行匹配,…
result = fullmatch('\\d3|[a-z]2', 'mn')
print(result)
# 'abc34', 'abcKJ', 'abc78', 'abcOP'
result = fullmatch(r'abc\\d\\d|abc[A-Z]2', 'abcJK')
print(result)
result = fullmatch(r'abc(\\d\\d|[A-Z]2)', 'abcJK')
print(result)
4.转义符号
转义符号:在本身具有特殊功能或者特殊意义的符号前加 \\ ,让特殊符号变成普通
# 匹配整数部分和小数部分都是两位数的小数
result = fullmatch(r'\\d\\d\\.\\d\\d', '23.45')
print(result)
result = fullmatch(r'\\d\\+\\d', '3+7')
print(result)
# '(amd)'
result = fullmatch(r'\\([a-z]3\\)', '(jsk)')
print(result)
注意:单独存在有特殊意义的符号,在[]中它的功能会自动消失
result = fullmatch(r'\\d[+.?*()]\\d', '3+4')
print(result)
三、re模块
re模块:提供python中所有的和正则相关的函数
from re import fullmatch, findall, search, match, finditer, split, sub
- fullmatch(正则, 字符串) —— 用整个字符串和正则,匹配成功返回匹配对象,匹配失败返回None
- findall(正则, 字符串) —— 获取字符串中所有满足正则的子串,默认返回一个列表,列表中的元素是所有匹配到的子串(存在自动捕获现象)
- search(正则, 字符串) —— 匹配第一个满足正则的子串,匹配成功返回匹配对象,匹配失败返回None
- split(正则, 字符串) —— 将字符串中所有满足正则的子串作为切割点进行切割
- split(正则, 字符串, N) —— 将字符串中前N个满足正则的子串作为切割点进行切割
- sub(正则, 字符串1, 字符串2) —— 将字符串2中所有满足正则的子串都替换成字符串1
- sub(正则, 字符串1, 字符串2, N)
- finditer(正则, 字符串) —— 获取字符串中所有满足正则的子串,返回一个迭代器,迭代器中的元素是匹配对象
- match(正则, 字符串) —— 匹配字符串开头
注意
:python中表示一个正则表达式一般使用r字符串
str1 = '奇数偶数2亏待你489毒池234空'
print(split(r'\\d+', str1)) # ['奇数偶数', '亏待你', '毒池', '空']
print(split(r'\\d+', str1, 2)) # ['奇数偶数', '亏待你', '毒池234空']
print(sub(r'\\d', '+', str1)) # 奇数偶数+亏待你+++毒池+++空
message = '妈的,sb,都打起来了你还在打野!草!'
print(sub(r'妈的|sb|草|操|艹|f\\s*u\\s*c\\s*k', '*', message)) # *,*,都打起来了你还在打野!*!
str1 = '奇数偶数2亏待你489毒池234空'
result = finditer(r'\\d+', str1)
print(list(result)) # [<re.Match object; span=(4, 5), match='2'>, <re.Match object; span=(8, 11), match='489'>, <re.Match object; span=(13, 16), match='234'>]
# 1)忽略大小写:(?i)
print(fullmatch(r'(?i)abc', 'abc'))
print(fullmatch(r'(?i)abc', 'Abc'))
print(fullmatch(r'(?i)abc', 'ABc'))
print(fullmatch(r'(?i)abc', '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'>
message = """
'name:"jsdk2-
jisok"'
"""
result = findall(r'(?s)name:"(.+)"', message)
print(result) # ['jsdk2-\\njisok']
练习
使用正则提取豆瓣top250每个电影的详情页地址
import requests
from re import findall
headers =
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/111.0.0.0 Safari/537.36',
'cookie': 'BIDUPSID=A680D8CEFEAC65307965AEEFA7386849; PSTM=1677116640; BAIDUID=A680D8CEFEAC6530CC088914CFB657B3:FG=1; BD_UPN=12314753; BAIDUID_BFESS=A680D8CEFEAC6530CC088914CFB657B3:FG=1; ZFY=vaDaTi368yipgGZpVQL00KrnlEz88JWZ20zpNYGQVtI:C; COOKIE_SESSION=403843_1_4_7_3_6_1_0_3_5_2_0_403842_0_4_0_1679110087_1678182048_1679110083%7C7%230_1_1678182042%7C1; channel=chdb.s.3jdh.com; __bid_n=1870eeee282c21eba74207; FPTOKEN=4+MpAYwzZnRqgzjxYNT0wbLcN0FjxfEfFnUlkJWXqyZtczFiDKJ0FxsNExLcE9Cpyiw/SzLS9xWcLiCpFeXd5HZ+Sbta4AwRaWkwe2hvpdbS8HgcT67wnaS5uyUf0wyk3h5LtG5idaJxa1cnlcttmtX7qFsOS9iU/P3QpqP/haHj1bQvLTjpqvqhDHYHU6CRNZT63r0gAch/p61KQbClHaGTYdM+L4HcMxfj1AEgI4cz61fgJwFtuSY0ijK1lpO1nM5f6fLxn3tQz+1wfARxIQ86Vb43lw6yi3AX8sgxJLEIC+8+xQtH+3yZcBqQOMURZYcprAEQfdfCr+ytxMHyGoYGHHgatbhWOSbtqAIWKko45z6WDTCmChXZsYVp41BkSOIan5UbXCDwnO0jmVICBg==|kXj3FDr48e1/ID2yF1sMI09I3hp//yzUWBBKMcHnctk=|10|159a962b16701ba8d05dac30b2e0613c; BDRCVFR[PgFsD-oVCXs]=Sgq2UtKbV53nvGbpa4WUvY; delPer=0; BD_CK_SAM=1; PSINO=7; H_PS_PSSID=26350; BA_HECTOR=0h8h04ala005a08g802h24f21i22gla1n; BDORZ=FFFB88E999055A3F8A630C64834BD6D0; baikeVisitId=96d6d66c-40fa-4df5-9050-b5dd62676860; B64_BOT=1; ab_sr=1.0.1_NmRlMWExYTJmMDgxMTk3NmQ3MGMyMTA0N2I0M2ZkMmViZThhNWYzNGE2MmQ4NDYwYmY4YzE5YzYyMGZlZjJkMmZkY2Y3OWZlZGI3MjVlZmQxODY4ZWFiNTVkYTg1ZjExN2I0MmRlNGVmZWM0MDFlYzcyOGU3YWIyZTAzMmE2ZmZhNzdlNzczMDFlNGFkZjVhNTkxYjlkOWYxOTQ2ZjE1Nw==; H_PS_645EC=53dc0TItHpWat2m269u0gLvvlXcIkQKUs9AgCcryoRf2fMxOithlPnm1eJMXHPDZ5EuPZGND2L5b; BD_HOME=1'
response = requests.get('https://movie.douban.com/top250?start=0&filter=', headers=headers)
# 方法1
result = list(set(findall(r'https://movie.douban.com/subject/.+?/', response.text)))
print(result)
# 方法2
result = findall(r'<a href="(.+?)" class=""', response.text)
print(result)
Day 26 python 正则表达式
re模块\正则表达式
一、元字符
1、. ^ $ * + ? { } [ ] | ( ) \
"." 代表(任意一个字符) "*" 代表(任意数量任意字符,0-无穷) "+" 代表(任意一个或无数字符,1-无穷) "?" 代表(0或1个字符) "^" 代表(字符串开头) "$" 代表(字符串结尾) "{}" 代表(指定次数)
2、转义符 \
1)、反斜杠后边跟元字符去除特殊功能,比如\.
2)、反斜杠后边跟普通字符实现特殊功能,比如\d
\d 匹配任何十进制数; 它相当于类 [0-9]。 \D 匹配任何非数字字符; 它相当于类 [^0-9]。 \s 匹配任何空白字符; 它相当于类 [ \t\n\r\f\v]。 \S 匹配任何非空白字符; 它相当于类 [^ \t\n\r\f\v]。 \w 匹配任何字母数字字符; 它相当于类 [a-zA-Z0-9_]。 \W 匹配任何非字母数字字符; 它相当于类 [^a-zA-Z0-9_] \b 匹配一个特殊字符边界,比如空格 ,&,#等
3、分组 ()
ret = re.findall("(yuan)+","lalal11yuanhao22yuanyuanhaohao33yuan") #分组(),用findall命令返回的是分组内容 print(ret) #[‘yuan‘, ‘yuan‘, ‘yuan‘]
以上是关于day2023-3-28-正则表达式的主要内容,如果未能解决你的问题,请参考以下文章