正则表达式

正则表达式

基础知识

在线验证网址:www.regex101.com
在这里插入图片描述

  • 提取的页面源代码本质上就是一个超长的字符串,可利用正则表达式准确提取内容

  • 使用表达式的方式对字符串进行匹配的语法规则

  • 优缺点

    • 优点:速度快、效率高、准确性高

    • 缺点:上手慢

  • 语法格式:

    • 使用元字符进行排列组合从而来匹配字符串
    • 元字符:具有固定含义的特殊字符
  • 作用

    • 正则表达式是一种用于描述字符串模式的语言,可以用于匹配、查找、替换等操作。
  • 常见元字符

元字符解释
.(贪婪)匹配除了换行符之外的任何单个字符,详见例1
*(贪婪)匹配前面的子表达式任意次,包括0次,详见例2
+(贪婪)匹配前面的子表达式任意次,注意:不包括0次,详见例3
{num1,num2}表示前面的字符匹配指定的次数(至少num1次,至多num2次),可用于提取电话号码等,详见例4
\转义字符,作用:(1)将元字符变为普通字符,详见例5;(2)后接一些字符,表示匹配某种类型的一个字符
\d匹配任意一个0~9之间的数字字符,等价于表达式[0-9],详见例6
\D匹配任意一个不是0~9之间的数字字符,等价于表达式[^0-9],详见例7
\s匹配任意一个空白字符,包括空格、tab、换行符等,等价于表达式[\t\n\r\f\v]
\S匹配任意一个非空白字符,等价于表达式[^\t\n\r\f\v]
\w匹配任意一个文字字符,包括大小写字母、数字、下划线,等价于表达式[a-zA-Z0-9_],常见于判断用户名、密码是否规范,具体内容详见例8
\W匹配任意一个非文字字符,等价于表达式[^a-zA-Z0-9_]
[ab]匹配方括号内a或b。例子:[\s,.]表示匹配任何空白字符或者逗号或者点,详见例9
[^]方括号中使用^,表示非的概念,即非方括号里面的字符集合,详见例10
^表示匹配文本的起始位置,若是单行模式则表示匹配整个文本的开头位置;若是多行模式则表示匹配文本每行的开头位置,详见例11
$表示匹配文本的结束位置,若是单行模式则表示匹配整个文本的结束位置;若是多行模式则表示匹配文本每行的结束位置,详见例12
()组选择,代表从正则表达匹配的内容里面扣取出其中的某些部分,详见例13
?表示匹配前面的子表达式0次或1次,详见例14
?P<name>此为命名捕获组语法,用来给给匹配的数据命名。详见例15 注意: 命名后提取数据的方式跟不命名不一样,详见例题

贪婪模式和非贪婪模式

点、星号、加号都是贪婪地,使用它们时,会尽可能多的匹配内容,如图所示在这里插入图片描述

解决办法:

加上问号即可
在这里插入图片描述

re库

  • 需要导入re库:

Python 的 re(regular expression,正则表达式)库是用于处理正则表达式的标准库,它提供了一些函数和方法,用于对字符串进行模式匹配和查找。使用正则表达式可以方便地对字符串进行复杂的匹配和操作。

  • re库中常用的函数和方法
函数和方法解释
re.match(pattern, string, flags=0)从字符串的开头开始匹配,如果字符串开头不符合正则表达式,返回 None;如果符合则返回一个MatchObject对象
re.search(pattern, string, flags=0)在字符串中查找符合正则表达式的第一个子串,如果找到返回一个匹配的MatchObject对象,否则返回 None。
rre.findall(pattern, string, flags=0)查找字符串中符合正则表达式的所有子串,并返回一个匹配对象的列表。注意:不是返回一个MatchObject对象
str.replace(old, new,count)不是re库中的替换方法函数。old:原字符串;new:替换old的新字符串;count:为指定最多的替换次数,默认为-1,代表替换所有的匹配项
re.sub(pattern, repl, string, count=0, flags=0)在字符串中查找符合正则表达式的子串,并用指定的字符串替换它们。
re.split(pattern, string, maxsplit=0, flags=0)按照正则表达式的匹配结果将字符串分割成若干个子串,并返回一个列表。
re.compile(pattern, flags=0)编译正则表达式字符串,提前将其编译成一个正则表达式对象(预加载)。作用:(1)避免每次解析正则表达式字符串的开销并提高匹配效率(2)可对其利用re库中的各种方法进行处理
re.findall(pattern, string)在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
re.finditer(pattern, string)用于在字符串中查找所有匹配正则表达式的子串,并返回一个迭代器。每个迭代器元素都是一个MatchObject对象,包含匹配的子串及其位置等信息。如图所示

若返回一个MatchObject对象,则需要用obj.group()来获取得到的结果
在这里插入图片描述

参数解释
pattern要匹配的正则表达式,可以是正则表达式字符串或正则表达式对象(若为正则表达式对象则可通过re.compile()编译得到)
string需要匹配的字符串
flags可选参数,用于指定正则表达式的标志位,例如“re.IGNORECASE”可用于忽略大小写"re.A"可用于在只选择英文文字字符时变更选择的编码(缺省为unicond编码,即可匹配任何字符);“re.MULTILINE”等同于"re.M"代表多行模式(缺省为单行模式)“re.S” 表示"点任意匹配模式",即"."可以匹配包括换行符在内的任意字符。
repl替换字符串,可以是一个字符串或一个函数
count可选参数,用于指定最多替换的次数。
maxsplit可选参数,用于指定最多分割的次数。
  • 注意

(1)关于re.findall(pattern, string) 函数:

​ 若未使用compile()函数将其字符串变为正则表达式对象,则你需要写pattern;反之则只需要引入string即可,详见例题1的两种方式

(2)在利用python进行爬虫时,re.finditer()方法和re.compile()方法的区别,用哪个更好?

re.compile()方法用于将正则表达式编译为一个正则表达式对象(即预加载,提前把正则对象加载完毕)以便在后续的匹配中重复使用。而re.finditer()方法用于在字符串中查找所有匹配正则表达式的子串,并返回一个迭代器。

​ 如果需要在多个字符串中多次使用同一个正则表达式,那么使用re.compile()方法可以提高效率。因为编译后的正则表达式对象可以被多次调用,而不需要重新解析正则表达式。而如果只需要在一个字符串中查找匹配的子串,那么使用re.finditer()方法即可

​ 总之,以上两种方法均能提高效率!!!爬虫时可根据实际情况选择。

常见re库中方法的举例

re.finditer()方法
import re
result = re.finditer(r'\d+', "我今年18岁,我有2000万")
for i in result:
    print(i)#返回迭代器
    print(i.group())#从迭代器中返回匹配到的结果

在这里插入图片描述

re.search()方法
import re
result = re.search(r'\d+',"我叫周杰伦,我今年25岁了,我是3年纪2班的学生")
print(result)
#注意:re.search()方法返回的也是一个match对象,所以需要用group方法提取match对象中的数据
print(result.group())

在这里插入图片描述

re.match()方法
import re
result = re.match(r'\d+',"我叫周杰伦,我今年25岁了,我是3年纪2班的学生")
print(result)
print(result.group())

在这里插入图片描述

import re
result = re.match(r'\d+',"25岁的周杰伦,是3年纪2班的学生")
print(result)
print(result.group())

在这里插入图片描述

例题

01 .

例题1:从下面的例子中选择出所有的颜色

苹果是绿色的

橙子是橙色的

香蕉是黄色的

方式一

在这里插入图片描述

方式二

在这里插入图片描述

02 *

例题2:选择文本中逗号后的内容,包括逗号

注意:

.代表单个字符,然后在加上*代表任意个字符

在这里插入图片描述

03 +

例题3:选择文本中逗号后的内容,包括逗号

注意:.代表单个字符。最后一句话中的逗号后没有字符,所以不满足元字符+的条件

在这里插入图片描述

注意: 由于最后一句话中没有出现色字,不满足元字符+的条件,所以结果中没有黑

在这里插入图片描述

04 {}

例题4:{}可用于提取电话号码

在这里插入图片描述

05 \

例题5:返回所有点前面的字符串

在这里插入图片描述

06 \d

例题6:\d 匹配任意一个0~9之间的数字字符,等价于表达式[0-9]

在这里插入图片描述

07 \D

例题7:匹配任意一个不是0~9之间的数字字符,等价于表达式[^0-9]

在这里插入图片描述

08 \w

例题8:\w 匹配任意一个文字字符,包括大小写字母、数字、下划线,等价于表达式[a-zA-Z0-9_],常见于判断用户名、密码是否规范

注意:

若不做特殊设置,则会匹配中文、英文所有文字字符,如下:

在这里插入图片描述

若只想匹配英文文字字符,则需要在re.compile()函数的参数中加上参数flags,即re.A(作用:选择编码值)如下:
在这里插入图片描述

09 [ab]

例题9:[ab] 匹配方括号内a或b。例子:[\s,.]表示匹配任何空白字符或者逗号或者点

在这里插入图片描述
在这里插入图片描述

10 [^]

例题10:[^] 方括号中使用^,表示非的概念,即非方括号里面的字符集合

在这里插入图片描述

11 ^

例题11:^ 表示匹配文本的起始位置,若是单行模式则表示匹配整个文本的开头位置;若是多行模式则表示匹配文本每行的开头位置

单行模式

在这里插入图片描述

多行模式

在这里插入图片描述

12 $

例题12:$ 表示匹配文本的结束位置,若是单行模式则表示匹配整个文本的结束位置;若是多行模式则表示匹配文本每行的结束位置

单行模式

在这里插入图片描述

多行模式
在这里插入图片描述

13()

例题13:()组选择,代表从正则表达匹配的内容里面扣取出其中的某些部分

在这里插入图片描述

14 ?

例题14:? 表示匹配前面的子表达式0次或1次

在这里插入图片描述

15 ?P<name>

?P<name> 此为命名捕获组语法,用来给给匹配的数据命名

注意: 命名后,相当于将数据分为了不同的组别。此时就不能用findall()方法来得到数据,而是用finditer()方法来返回一个MatchObject对象数据,然后利用obj.group()方法来得到不同组别的数据

import re
a = '''
<div class = '西游记'><span id = '10010'>中国联通</span></div>
<div class = '西游记'><span id = '10086'>中国移动</span></div>
'''
#?P<name>
p = re.compile(r"<span id = '(?P<id>\d+)'>(?P<name>.+)</span>")
for i in p.finditer(a):
    print(i.group("id") + ':' + i.group("name"))
    # print(i.group("name"))

在这里插入图片描述

16 总训练

Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8万/月02-18剩余255人python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5万/每月02-18满员

例题15 :从以上文本中提取出工资

在这里插入图片描述

切割字符串

字符串 对象的 split 方法只适用于 简单的字符串分割。 有时,你需要更加灵活的字符串切割。而正则表达式则适用于任何情况下的字符串分割

如下:

names = '关羽; 张飞, 赵云,马超, 黄忠  李逵'

若你想将人名切割出来,此时你仅仅利用split()方法就很困难,但是将其与正则表达式结合起来就很容易了
在这里插入图片描述

字符串替换

字符串 对象的 replace 方法只适应于 简单的 替换。 有时,你需要更加灵活的字符串替换

比如,我们需要在下面这段文本中 所有的 链接中 找到所以 /avxxxxxx/ 这种 以 /av 开头,后面接一串数字, 这种模式的字符串。

然后,这些字符串全部 替换为 /cn345677/

names = '''

下面是这学期要学习的课程:

<a href='https://www.bilibili.com/video/av66771949/?p=1' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是牛顿第2运动定律

<a href='https://www.bilibili.com/video/av46349552/?p=125' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是毕达哥拉斯公式

<a href='https://www.bilibili.com/video/av90571967/?p=33' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是切割磁力线
'''

被替换的内容不是固定的,所以没法用 字符串的replace方法。

此时,可以使用正则表达式里面的 sub 方法

import re
names = '''

下面是这学期要学习的课程:

<a href='https://www.bilibili.com/video/av66771949/?p=1' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是牛顿第2运动定律

<a href='https://www.bilibili.com/video/av46349552/?p=125' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是毕达哥拉斯公式

<a href='https://www.bilibili.com/video/av90571967/?p=33' target='_blank'>点击这里,边看视频讲解,边学习以下内容</a>
这节讲的是切割磁力线
'''
#match是一个类,match
def subFunc(match):
    #match对象的group(0)代表返回的是整个匹配上的字符串
    src = match.group(0)#等同于src = match[0](python3.6之后)
    #match对象的group(1)代表返回的是第一个group分组的内容,也就是返回用第一个()括起来的内容
    number = int(match.group(1)) + 6#等同于number = int(match[1]) + 6(python3.6之后)
    #若有match.group(2)代表返回用第二个()括起来的内容,在本次代码中只有一个括号,即r'/av(\d+?)/'
    
    dest = f'/av{number}/'#将字符串拼接起来
    
    print(f'{src}替换为{dest}')
    
    #返回值就是最终替换的字符串
    return dest
'''注意:
在re.sub()方法中,第二个参数可以是一个函数,用于处理匹配到的每个子串,将其替换为指定的字符串。当使用函数作为第二个参数时,re.sub()
方法会将每个匹配到的子串作为参数传递给该函数,并将函数的返回值作为替换后的字符串。
在这个例子中,subFunc()函数被传递给了re.sub()方法作为第二个参数。当re.sub()方法找到匹配的子串时,会将该子串作为参数传递给subFunc()
函数,并将函数的返回值作为替换后的字符串。因此,subFunc()函数需要接受一个match对象作为参数,并返回一个字符串作为替换后的结果。
'''
newStr = re.sub(r'/av(\d+?)/', subFunc, names)
print(newStr)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT机器猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值