当前位置: 首页 > news >正文

《零基础入门学习Python》第058讲:论一只爬虫的自我修养6:正则表达式2

上一节课我们通过一个例子(匹配 ip 地址)让大家初步了解到正则表达式的魔力,也让大家充分了解到学习正则表达式是一个相对比较困难的事情。所以这一节课我们将继续学习 正则表达式的语法。

我们依稀还记得在Python中,正则表达式是以字符串的形式来描述的,正则表达式的强大之处在于特殊符号的应用,我们上节课举了例子,例如 点号(.),在正则表达式中表示匹配除了 换行符之外的任何字符,它就是一个特殊的字符。正是这些特殊符号,使得一个正则表达式可以匹配一个复杂的规则,而不仅仅是匹配一个字符串,如果你只需要匹配一个字符串,那用 find() 方法就可以了。

我这里给大家准备了一个列表,Python3 正则表达式特殊符号及用法(详细列表)。

这里罗列了python3 所支持的所有正则表达式的特殊符号以及具体的含义,在难以理解的地方,用斜体举了例子给大家看,方便大家理解,大家可以将这个文章收藏起来,以后用到的时候查询就可以了,切记不要死记硬背,因为根本背不住,如果背错了更扎心。

大家看到这里,可能就会犯嘀咕了:“好歹我也是见过世面的人啊,为了查找一个字符串,有必要掌握这么多规则吗?”。

实话说,没必要。我这里只是给大家做一个总结,我们正常使用的情况下,只是使用这里的一小部分,另外一大部分只是为了应对突发情况而准备的。例如某一天,你心血来潮,想为你的规则再增加复杂一点的规则,那么这里边正则表达式就可以应付自如了。一定要记住的是,这里面的东西不要去背,多做练习才是重要的啊。你掌握的东西才是你的,背下来的东西过两天就不是你的了。

特殊符号是由两部分组成的,一部分是 元字符。(例如我们上节课讲的 点号(.),方括号([]),反斜杠(\)等)。

所有的元字符包括:.   ^    $     *     +     ?     { }     [ ]     \     |     ( )  

另一部分就是 反斜杠加上普通符号组成的特殊符号,它拥有特殊的含义。

首先来谈谈元字符:

点号(.):是匹配除了换行符之外的任何字符。

| :就相当于逻辑或,学过C语言的同学们都知道,这就是按位或。A|B 表示匹配正则表达式 A或者B

例如:

 
  1. >>> import re

  2. >>> re.search(r"Python(E|F)", "PythonE")

  3. <_sre.SRE_Match object; span=(0, 7), match='PythonE'>

  4. >>> re.search(r"Python(E|F)", "PythonF")

  5. <_sre.SRE_Match object; span=(0, 7), match='PythonF'>

  6. >>> re.search(r"Python(E|F)", "PythonD")

  7. >>>

托字符(^):定位匹配,匹配字符串的开始位置(即确定一个位置)。

例如:

 
  1. >>> re.search(r"^Python", "I love Python")

  2. >>>

  3. >>> re.search(r"^Python", "Python, I love")

  4. <_sre.SRE_Match object; span=(0, 6), match='Python'>

跟托字符(^)对应的就是 美元符号($),$ 匹配输入字符串的结束位置.

 
  1. >>> re.search(r"Python$", "Python, I love")

  2. >>>

  3. >>> re.search(r"Python$", "I love Python")

  4. <_sre.SRE_Match object; span=(7, 13), match='Python'>

我们刚刚提到了值组,就是用小括号括起来的,我们上节课也用过了,用小括号括起来跟数学的括号是一样的,把一个东西当做一个整体,那么就把它括起来。

接下来是史上最困难、最复杂的 反斜杠(\),反斜杠在正则表达式中应用是最广泛的,它既可以将一个普通的字符变为特殊字符(这部分内容下节课继续讲解),同时也可以解除元字符的特殊功能,这在上节课已经讲过,例如 \. 匹配的就不是除换行符之外的任何字符了,他匹配的就是一个点(.)了。

如果在反斜杠后面加的是数字,那么还有两种表示方案:

①如果跟着的数字是 1~99,就表示引用序号对应的值组所匹配的字符串,其中序号所对应的值组:为 \ 前面的值组,\序号必须在对应的值组的正后面,序号为第几个值组。

例如:

 
  1. >>> re.search(r"(Python)\1", "I love Python")

  2. >>>

  3. >>> re.search(r"(Python)\1", "I love PythonPython")

  4. <_sre.SRE_Match object; span=(7, 19), match='PythonPython'>

上面的(Python)是第一个值组(序号是从1开始计算的,因为0表示一个八进制数),所以 \1,且\1 表示Python,其实 r'(Python)\1' 就等于 'PythonPython'。

 
  1. >>> re.search(r"(love)(Python)\1", "I lovelovePythonPython") #这样\1 是找不到 (love)的,\序号必须在对应值组的正后方

  2. >>>

  3. >>> re.search(r"(love)\1(Python)", "I lovelovePythonPython")

  4. <_sre.SRE_Match object; span=(2, 16), match='lovelovePython'>

  5. >>> re.search(r"(love)(Python)\2", "I lovelovePythonPython")

  6. <_sre.SRE_Match object; span=(6, 22), match='lovePythonPython'>

  7. >>> re.search(r"(love)\1(Python)\2", "I lovelovePythonPython")

  8. <_sre.SRE_Match object; span=(2, 22), match='lovelovePythonPython'>

并不是要求全部都要是值组,是要求 \序号 匹配的是值组:

 
  1. >>> re.search(r"(I )love(Python)\2", "I lovePythonPython.com")

  2. <_sre.SRE_Match object; span=(0, 18), match='I lovePythonPython'>

②如果跟着的数字是 0 或者 3位的数字,那么它是一个八进制数,表示的是这个八进制数对应的 ASCII 码对应的字符。

例如:字符 0 对应的十进制数为 48,对应的八进制数为 60,这里要三位数,就是060,所以:

 
  1. >>> re.search(r"\060", '0')

  2. <_sre.SRE_Match object; span=(0, 1), match='0'>

 
  1. >>> re.search(r"I love Python\060", 'I love Python0')

  2. <_sre.SRE_Match object; span=(0, 14), match='I love Python0'>

接下来要介绍的元字符是 中括号([ ]),这是生成一个字符类,事实上,字符类就是一个字符集合的意思,另外,值的注意的是:被中括号包含在里面的元字符都会失去特殊功能,就像 反斜杠加上一个元字符是一样的,举例:

 
  1. >>> re.search(r"[.]", 'I love Python.com')

  2. <_sre.SRE_Match object; span=(13, 14), match='.'>

字符类的意思就是将它里面的内容都当做普通的字符看待,除了几个特殊的字符:

①小横杠(-),我们用它表示范围,我们上节课讲过,这节课我们讲一个其他的方法:re.findall()

re.findall

在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个列表返回。

re.findall(pattern, string, flags=0)

参数:

参数描述
pattern匹配的正则表达式
string要匹配的字符串。
flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
 
  1. >>> re.findall(r"[a-z]","12a32bc43jf3")

  2. ['a', 'b', 'c', 'j', 'f']

findall 和 search 相比,似乎更符合我们的需求,但是当遇到值组时,findall 也会有陷阱,我们后面会讲解。

②反斜杠(\),把反斜杠放在字符类[ ]中,它也不是表示本身,这样会报错,

 
  1. >>> re.findall(r"[\]","12a32bc43jf3")

  2. Traceback (most recent call last):

  3. File "<pyshell#47>", line 1, in <module>

  4. re.findall(r"[\]","12a32bc43jf3")

  5. File "D:\ProgramFiles\Anaconda3\lib\re.py", line 213, in findall

  6. return _compile(pattern, flags).findall(string)

  7. File "D:\ProgramFiles\Anaconda3\lib\re.py", line 293, in _compile

  8. p = sre_compile.compile(pattern, flags)

  9. File "D:\ProgramFiles\Anaconda3\lib\sre_compile.py", line 536, in compile

  10. p = sre_parse.parse(p, flags)

  11. File "D:\ProgramFiles\Anaconda3\lib\sre_parse.py", line 829, in parse

  12. p = _parse_sub(source, pattern, 0)

  13. File "D:\ProgramFiles\Anaconda3\lib\sre_parse.py", line 437, in _parse_sub

  14. itemsappend(_parse(source, state))

  15. File "D:\ProgramFiles\Anaconda3\lib\sre_parse.py", line 545, in _parse

  16. source.tell() - here)

  17. sre_constants.error: unterminated character set at position 0

反斜杠在字符类里,表示Python 字符串的转义符。

在字符串里,我们都知道 \n 表示回车的意思,所以:

 
  1. >>> re.findall(r"[\n]","12a32\nbc43jf3")

  2. ['\n']

③托字符 ^,在字符类[ ]里,表示‘除了’(取反)的意思,但是要注意的是,这个托字符 ^ 必须放在最前面:

 
  1. >>> re.findall(r"[^a-z]","12a32bc43jf3")

  2. ['1', '2', '3', '2', '4', '3', '3']

如果放在后面,就是表示匹配它本身:

 
  1. >>> re.findall(r"[a-z^]","12a32bc^^43jf3")

  2. ['a', 'b', 'c', '^', '^', 'j', 'f']

最后要介绍的元字符 是用于做重复的事情,例如我们上节课讲到的 大括号{ },如{M,N}(要求M,N均为非负整数,且M<=N)表示前面的内容匹配 M~N次。

 
  1. >>> re.search(r'Python{3}', 'I love Pythonnn')

  2. <_sre.SRE_Match object; span=(7, 15), match='Pythonnn'>

 
  1. >>> re.search(r'(Python){3}', 'I love PythonPythonPython')

  2. <_sre.SRE_Match object; span=(7, 25), match='PythonPythonPython'>

在正则表达式中,需要注意的是,大家在写编程的时候,可能会注意美观,可能会多加一些空格,但是在正则表达式里面,你千万不能加空格,例如:

 
  1. >>> re.search(r'(Python){1,5}', 'I love PythonPythonPython')

  2. <_sre.SRE_Match object; span=(7, 25), match='PythonPythonPython'>

 
  1. >>> re.search(r'(Python){1, 5}', 'I love PythonPythonPython')

  2. >>>

因为空格会被解析为一个正则表达式。

最后,我们来谈一下几个特殊的:

①星号(*):匹配前面的子表达式零次或多次,等价于 {0,}

②加号(+):匹配前面的子表达式一次或多次,等价于 {1,}

③问号(?):匹配前面的子表达式零次或一次,等价于 {0,1}

在正则表达式中,如果实现条件一样,推荐大家使用左边的 *  +  ?这三个,不要使用 大括号{ },因为:首先,星号、加号、问号更加简洁;其次,正则表达式内部会对这三个符号进行优化,效率会比使用大括号要高一些。

最后,我们来谈一下 贪婪 和 非贪婪。

关于我们这个 重复 的操作,有一点需要注意的就是:正则表达式默认是启用 贪婪 的模式来进行匹配的,那什么是 贪婪 呢?贪婪就是贪心,也就是说,只要在符合的条件下,它会尽可能多的去匹配,例如前面的 re.search(r'(Python){1,5}', 'I love PythonPythonPython') 就会直接匹配到3个 Python。

我们来看一个现实中的案例。假设我们想 匹配 <html> 

 
  1. >>> s = "<html><title> I love Python.com</title></html>"

  2. >>> re.search(r"<.+>", s)

  3. <_sre.SRE_Match object; span=(0, 46), match='<html><title> I love Python.com</title></html>'>

<.+> 表示以 < 开头,以 > 结尾,重复 . 号 1次或多次。最后匹配了字符串全部。很明显,这不是我们想要的结果。

因为贪婪会在条件符合的情况下尽可能多的去匹配,既然是这样,我们就必须启用 非贪婪模式才可以,那么非贪婪模式怎么样启用呢?

很简单,在表示重复的元字符后面再加上一个问号,这时候,问号就不代表0次或1次了,而是表示启用非贪婪模式:

 
  1. >>> re.search(r"<.+?>", s)

  2. <_sre.SRE_Match object; span=(0, 6), match='<html>'>

好了,到这里,正则表达式的所有元字符我么就讲解完毕了,大家课后一定要勤加练习。

相关文章:

《零基础入门学习Python》第058讲:论一只爬虫的自我修养6:正则表达式2

上一节课我们通过一个例子&#xff08;匹配 ip 地址&#xff09;让大家初步了解到正则表达式的魔力&#xff0c;也让大家充分了解到学习正则表达式是一个相对比较困难的事情。所以这一节课我们将继续学习 正则表达式的语法。 我们依稀还记得在Python中&#xff0c;正则表达式是…...

第一堂棒球课:MLB棒球大联盟的主要战术·棒球1号位

MLB棒球大联盟的主要战术 攻击战术run-and-foul&#xff08;跑垒战术&#xff09;&#xff1a;以速度为优势&#xff0c;在适当的时机发动进攻&#xff0c;争取在一回合内完成得分。 grounder&#xff08;阻截战术&#xff09;&#xff1a;队员在垒包之间阻止对手的跑垒和传球。…...

【论文阅读】利用道路目标特征的多期车载激光点云配准

目录 引 言1 道路场景点云特征2 配准方法2.1 配准基元获取2.2 特征点提取2.3 两期道路场景车载点云的配准 2.3.1 基于特征点的4PCS 粗配准 3 实验与分析4 结论5 参考文献 摘 要 针对车载移动测量系统获取的城市道路点云场景巨大、目标复杂多样&#xff0c;多期道路场景重访车载…...

L---泰拉瑞亚---2023河南萌新联赛第(三)场:郑州大学

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 示例1 输入 1 10 3 5 输出 3 说明 只有一把回旋镖&#xff0c;你可以先打两次伤害为3的&#xff0c;再打一次倾尽全力的&#xff0c;造成的伤害为5。总伤害为33511&#xff0c;即可获得胜…...

windows无盘启动技术开发之使用本地镜像文件启动电脑

by fanxiushu 2023-07-26 转载或引用请注明原始作者。 其实使用本地镜像文件启动电脑&#xff0c;这个windows操作系统本身就是自带的功能。 win7以上的系统&#xff0c;制作 vhd或vhdx格式的镜像文件&#xff0c; 然后在镜像文件中安装windows操作系统&#xff0c;然后放到真实…...

PoseiSwap 即将开启质押,利好刺激下 POSE通证短时涨超 30%

随着 Nautilus Chain 主网的上线&#xff0c;预示着 Web3 世界迎来全新的模块化、Layer3 时代&#xff0c;为 Web3 世界与 Web2 世界的深入融合构建基础。而 PoseiSwap 作为 Nautilus Chain 上的首个 DEX&#xff0c;也成为了加密行业首个以模块化为基础构建的 DEX。 基于 Naut…...

Linux文本编辑器-vim

目录 前言 Vim三种模式 打开方式 命令模式 插入模式 可视模式 保存和退出 前言 Vim是一个功能丰富且强大的文本编辑器&#xff0c;被广泛用于Linux系统。它是Vi的增强版本&#xff0c;提供了更多的功能和改进&#xff0c;同时可以通过插件扩展其功能&#xff1b; Vim三…...

vscode使用g++编译.c文件或.cpp文件

vscode是一个跨平台、轻量级、插件非常丰厚的IDE&#xff0c;这里介绍在vscode里使用g来编译.cpp文件。g也叫GCC, 在Window中&#xff0c;是使用MinGW方式实现g的&#xff0c;它分为32位和64位2个版本&#xff0c;其中&#xff0c;MinGW-64是64位的&#xff0c;MinGW-32是32位的…...

云计算的服务模式包括哪些|PetaExpress云服务商

云计算&#xff08;cloud computing&#xff09;它是一种分布式计算&#xff0c;是指通过网络“云”将巨大的数据计算处理程序分解成无数的小程序&#xff0c;然后通过由多个服务器组成的系统进行处理和分析&#xff0c;得到结果并返回给用户。云计算作为一种基于互联网的新型超…...

iOS--通知、代理、单例模式总结

通知 概要 观察者和被观察者都无需知晓对方&#xff0c;只需要通过标记在NSNotificationCenter中找到监听该通知所对应的类&#xff0c;从而调用该类的方法。并且在NSNotificationCenter中&#xff0c;观察者可以只订阅某一特定的通知&#xff0c;并对齐做出相应操作&#xf…...

选择最佳安全文件传输方法的重要性

在数字化时代&#xff0c;文件的传输是商务、教育、科研、医学等领域不可或缺的工作流程。为了保障数据安全&#xff0c;选择最佳安全文件传输方法非常关键。在本文中&#xff0c;我们将探讨选择最佳安全文件传输方法的重要性。 第一、最佳安全文件传输方法可以保证文件内容不被…...

IBM LSF 集群虚拟化和工作负载管理解决方案

IBM LSF 集群虚拟化和工作负载管理解决方案 全面综合的工作负载管理解决方案&#xff0c;不仅能够简化 HPC&#xff0c;还能大幅改善用户和管理员体验、可靠性和性能 用途 IBM Spectrum LSF Suites 组合通过为任务关键型 HPC 环境提供集成解决方案&#xff0c;重新定义集群虚…...

C++(14):重载运算与类型转换

当运算符被用于类类型的对象时&#xff0c;允许我们为其指定新的含义&#xff1b;同时&#xff0c;也能自定义类类型之间的转换规则。和内置类型的转换一样&#xff0c;类类型转换隐式地将一种类型的对象转换成另一种我们所需类型的对象。 当运算符作用于类类型的运算对象时&a…...

【深度学习】基于图形的机器学习:概述

一、说明 图神经网络&#xff08;GNN&#xff09;在数据科学和机器学习中越来越受到关注&#xff0c;但在专家圈之外仍然知之甚少。为了掌握这种令人兴奋的方法&#xff0c;我们必须从更广泛的图形机器学习&#xff08;GML&#xff09;领域开始。许多在线资源谈论GNN和GML&…...

内存泄漏是什么?有什么危害

内存泄漏是什么&#xff1f;有什么危害 1. 前言1.内存泄漏是什么&#xff1f;2. 为什么会发生内存泄漏3. 内存泄漏的危害4. 总结 1. 前言 在各种项目开发中&#xff0c;内存泄漏是一个很严重的问题。对资源管理、性能优越、系统稳定性&#xff0c;以及是否安全产生极大印象。本…...

【项目设计】基于负载均衡的在线oj平台

目录 一、项目介绍 二、开发环境以及技术 三、概要设计 四、关键算法 五、项目演示 六、代码实现 一、项目介绍 该项目是基于负载均衡的在线oj&#xff0c;模拟平时刷题网站&#xff08;leetcode和牛客&#xff09;写的一个在线判题系统 项目主要分为五个模块&#xff…...

生产环境Session解决方案、Session服务器之Redis

目录 一、服务器配置 二、安装nginx 三、安装配置Tomcat&#xff1a; 四、配置session Session服务器之Redis Redis与Memcached的区别 安装部署redis 一、服务器配置 IP地址 主机名 软件包列表 192.168.100.131 huyang1 nginx 192.168.100.133 huyang3 JDK Tomca…...

SPECjvm2008_1_01 openjdk8 x86_64 ARM64 运行时长、成绩 Run is valid, but not compliant

i5-9600k 架构&#xff1a; x86_64CPU 运行模式&#xff1a; 32-bit, 64-bitAddress sizes: 39 bits physical, 48 bits virtual字节序&#xff1a; Little Endian CPU: 6在线 CPU 列表&#xff1a; …...

安卓:百度地图开发(超详细)

一、百度地图介绍 百度地图SDK是一套供开发者使用的软件开发工具包&#xff08;SDK&#xff09;&#xff0c;用于在Android应用程序中集成和使用百度地图功能。通过使用百度地图SDK&#xff0c;开发者可以实现在自己的应用中显示地图、获取定位信息、进行搜索、导航等功能。 百…...

DDSv1.4规范(中文版)

实时数据分发 (DDS) V1.4 (2015-04-10正式发布) https://www.omg.org/spec/DDS/1.4/PDF http://www.omg.org/spec/DDS/20140501/dds_dcps.idl...

oracle,获取每日24*60,所有分钟数

前言&#xff1a; 为规范用户的时间录入&#xff0c;因此我们采用下拉的方式&#xff0c;让用户选择需要的时间&#xff0c;因此我们需要将一天24小时的时间拆分为类似00:00,00:01...23:00,23:01,23:59。因此我们需要生成24*601440行的下拉复选值。具体效果如下图所示。 思路 1…...

vue elementui table去掉滚动条与实现表格自动滚动且无滚动条

当table内容列过多时&#xff0c;可通过height属性设置table高度以固定table高度、固定表头&#xff0c;使table内容可以滚动。 现在需求是右侧滚动条不好看&#xff0c;需要去除滚动条&#xff0c;并隐藏滚动条所占列的位置。让他可以滚动但是不出现滚动条,不然即时隐藏了滚动…...

SDK命令行工具配置

SDK命令行工具配置 最早的Android SDK工具包&#xff0c;包含一些GUI的工具。 而在一些场景&#xff08;如打包&#xff09;只需要命令行工具时&#xff0c;下载 command-line tools 即可。 到 Android Studio下载页 &#xff0c;找到 Command line tools only 下载。 命令…...

【数字IC基础】竞争与冒险

竞争-冒险 1. 基本概念2. 冒险的分类3. 静态冒险产生的判断4. 毛刺的消除使用同步电路使用格雷码增加滤波电容增加冗余项&#xff0c;消除逻辑冒险引入选通脉冲 1. 基本概念 示例一&#xff1a; 如上图所示的这个电路&#xff0c;使用了两个逻辑门&#xff0c;一个非门和一个与…...

速成版-带您一天学完python自动化测试(selenium)

Selenium是一套web网站的程序自动化操作解决方案。我们通过编写自动化程序&#xff0c;使得自动完成浏览器界面的相关操作&#xff0c;除了能够自动化的完成相关操作&#xff0c;还能从web页面获取相关信息&#xff0c;然后通过程序进行分析处理&#xff0c;本质上就是提升从网…...

windows 删除无法删除的文件

有两种原因&#xff1a; 文件被占用文件无权限 解决方案 通用解决方案是进入安全模式进行删除 安全模式&#xff1a; 不会启动非必要的进程有最高的系统权限 进入系统配置 安全引导&#xff0c;重启 删除文件 修改系统配置为正常启动 重启...

FFmpeg[7] - FFmpeg之预设编码参数preset

目录 前言 正文 一、定义与作用 二、取值范围 三、枚举值 四、使用实例...

CVPR2023新作:3D视频物体检测

Title: 3D Video Object Detection With Learnable Object-Centric Global Optimization Affiliation: 中国科学院自动化研究所 (Institute of Automation, Chinese Academy of Sciences)&#xff0c;中国科学院大学人工智能学院 (School of Artificial Intelligence, Univers…...

Keepalived热备、Keepalived+LVS、HAProxy监控及后端服务器健康检查、负载均衡调度器对比

day02 day02KeepAlived高可用集群配置高可用的web集群监控本机80端口&#xff0c;实现主备切换实现原理实施配置高可用、负载均衡的web集群配置高可用、负载均衡HAProxy配置haproxy负载均衡调度器比较LVS&#xff08;Linux Virtual Server&#xff09;NginxHAProxy KeepAlive…...

用Vue开发仿旅游站webapp项目总结 (上)

写着写着发现会写不少内容... 全部写在一篇文章里感觉太多了不方便看&#xff0c;所以分为上下篇吧... 下篇写完啦&#xff0c;感兴趣的朋友可以继续关注~ > 用Vue开发仿旅游站webapp项目总结 &#xff08;下&#xff09; 温馨提示 此文章&#xff0c;仅是做完项目后的个人…...