一文搞懂正则表达式之零宽断言

简介: 零宽断言:用于查找在某些内容之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。

正则表达式

正则表达式(英语:regular expression,常简写为regex、regexp或RE),又称规律表达式、正则表示式、正则表示法、规则表达式、常规表示法,是计算机科学概念,用简单字符串来描述、匹配文中全部匹配指定格式的字符串,现在很多文本编辑器都支持用正则表达式搜索、取代匹配指定格式的字符串。
--摘录自维基百科

总而言之,言而总之,正则表达式就是通过特定的字符来匹配特定的文本

零宽断言

简介

零宽断言: 简单来说就是用来判断一个规则之前或者之后的规则是否满足或者不满足

说起来有点迷糊对吧,举个例子就知道了:

这里有一个文本 "apple apple apple" ,可以看到有三个 ”apple“,并且中间用空格隔开,那现在我有个需求,我要匹配到中间 "apple",应该怎么做:

Tips: 本文使用的正则表达式测试网站是 https://regexr-cn.com/

/\sapple\s/

image cannot show

可以看到,虽然我们拿到了中间的 ”apple“,但是同时还顺带了旁边的空格,但我只想要 “apple” 怎么办,这时候就需要零宽断言来解决。

思考

但我们先不急着讲零宽断言,因为他的理论比较难懂,先来思考一下,如果是你,你的大脑会这么得到中间的 “apple”。首先中间的 “apple” 有什么特点,是不是左右两边都有空格?没错,这个空格就是关键,那么我们想要匹配到中间的 “apple”,是不是需要满足以下条件:

  1. 先有一个空格
  2. 再看接下来是不是 apple
  3. 最后看接下来是不是空格

那么可以随手写出来以下正则 /\sapple\s/,但是这不是和第一次写的一样吗,没错,这时候我们想想,两边的空格我们并不需要显示在结果中,但是我们需要匹配它,两边的空格仅仅是给我们作判断,所以我们来优化一下之前的步骤:

  1. 判断是否有空格
  2. 匹配apple
  3. 判断是否有空格

这里的 “判断”,我们换个词也可以说是 “断定”,那么我们就说这个不需要显示在结果中,但是我们需要匹配它的正则表达式是 “断言”,但我们又发现,我们不希望把断言匹配到的任何字符放到最终的结果中,它仅仅是做一个判断,所以它并不会改变任何字符,因此可以抽象的理解为,断言的 宽度为0,因此得名:零宽断言。

概念引入

零宽断言:

用于查找在某些内容之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。
--百度百科

仔细阅读上面的概念,有了之前的铺垫,应该就能很好理解 零宽断言 了。

再拿之前的案例来说,两边的空格就是断言,也就是说,在一个特定位置 “apple”,要同时判断左边的断言和右边的断言,我们称左边的断言是 “后发断言“,因为 ”apple“ 作为特定位置,它相对于左边的断言是在右边的,听起来可能有点绕,画个图就理解了。

image cannot show

那么左边的我们已经知道了是 “后发断言”,相反,右边的就是 先发断言?哈哈,这名字是不是怪怪的,其实他也有个专属的名字叫 “先行断言”。

但是,有没有发现我们现在的断言都是默认了符合要求的情况,事实上还有不符合要求的情况,那就是 在特定位置的前面或者后面的断言不符合时,则成功匹配。我们称这种行为是负向。

相反,在特定位置的前面或者后面的断言符合时,则成功匹配,我们称这种行为是正向

零宽断言的4种分类

Tip: 在网上你可能会看到各种各样的叫法,但是意思都一样,以下写的 “全称” 是规范完整的叫法

正向先行断言

全称:零宽度正预测先行断言
定义:当断言是真的,且判断当前位置(如之前说的apple)后面的字符是否符合某个模式(即断言)
语法:(?=exp) --> 其中exp为正则表达式
案例:一份学生名单,要求仅匹配出姓名为XiaoMing,且学号为2号的学生

XiaoMing  1
XiaoMing  2
LiHua     3

答案:

/XiaoMing(?=\s\s2)/

image cannot show

正向后发断言

全称:零宽度正回顾后发断言
定义:当断言是真的,且判断当前位置,前面的字符是否符合某个模式
语法:(?<=exp) --> 其中exp为正则表达式
案例:在以下菜谱中匹配出周三吃的所有菜

周一: 鱼香肉丝,番茄蛋汤
周二: 红烧鱼,猪肉汤
周三: 红烧鱼,番茄炒蛋
周四: 猪脚饭,红烧小排骨
周五: 骨肉相连,骨头汤

答案:

/(?<=周三..).+/

image cannot show

负向先行断言

全称:零宽度负预测先行断言
定义:当断言是假的,且判断当前位置,后面的字符是否符合某个模式
语法:(?!exp) --> 其中exp为正则表达式
案例:找出所有不是163邮箱的地址,要求返回完整邮箱地址

XiaoMing@163.com
XiaoAi@qq.com
LiHua@163.com
LiBai@126.com

答案:

/.+@(?!163\.com).+/g

image cennot show

负向后发断言(不常用)

全称:零宽度负回顾后发断言
定义:当断言是假的,且判断当前位置,前面的字符是否符合某个模式
语法:(?<!exp) --> 其中exp为正则表达式
案例:用负向后发断言匹配第一个 “apple”

apple apple apple

答案:

/(?<!\s)apple/

image cannot show

回顾开头

现在再来看文章最开始举的例子,是不是能很轻松拿捏了:有一段文本 "apple apple apple",中间用空格隔开,匹配出中间的 “apple”。

答案:

/(?<=\s)apple(?=\s)/
目录
相关文章
|
编解码 Linux 虚拟化
超详细VMware虚拟机安装Win10操作系统过程图解
这篇文章提供了一个详细的VMware虚拟机安装Windows 10操作系统的图解教程,包括了从创建虚拟机到安装操作系统的全过程,以及安装后的一些基本设置,如屏幕分辨率调整等。作者还提到了后续会分享关于磁盘分区的创建过程。
超详细VMware虚拟机安装Win10操作系统过程图解
|
10月前
|
数据可视化 算法 数据挖掘
用傅里叶变换解码时间序列:从频域视角解析季节性模式
本文介绍了如何使用傅里叶变换和周期图分析来识别时间序列中的季节性模式,特别是在能源消耗数据中。通过Python实现傅里叶变换和周期图,可以有效提取并量化时间序列中的主要和次要频率成分,克服传统可视化分析的局限性。这对于准确捕捉时间序列中的季节性变化具有重要意义。文章以AEP能源消耗数据为例,展示了如何应用这些方法识别日、周、半年等周期模式。
470 3
用傅里叶变换解码时间序列:从频域视角解析季节性模式
|
JavaScript 网络协议 前端开发
【Nodejs】WebSocket 全面解析+实战演练——(Nodejs实现简易聊天室)
【Nodejs】WebSocket 全面解析+实战演练——(Nodejs实现简易聊天室)
954 0
|
数据采集 Web App开发 JavaScript
爬虫策略规避:Python爬虫的浏览器自动化
爬虫策略规避:Python爬虫的浏览器自动化
|
Python
python类型错误(TypeError)
【7月更文挑战第13天】
594 9
|
人工智能 PyTorch TensorFlow
编程语言与工具:为AI开发选择合适的武器
【7月更文第15天】在人工智能(AI)领域,选择正确的编程语言和框架如同为战士挑选最合适的武器,它们能极大地影响项目进展的效率与成果。本文将深入探讨Python这一广泛应用于AI领域的编程语言,以及两个主流的深度学习框架——TensorFlow和PyTorch,为你提供决策时的参考依据。
834 1
|
缓存 分布式计算 算法
优化Hadoop MapReduce性能的最佳实践
【8月更文第28天】Hadoop MapReduce是一个用于处理大规模数据集的软件框架,适用于分布式计算环境。虽然MapReduce框架本身具有很好的可扩展性和容错性,但在某些情况下,任务执行可能会因为各种原因导致性能瓶颈。本文将探讨如何通过调整配置参数和优化算法逻辑来提高MapReduce任务的效率。
1393 0
|
Java
Java 实现 植物大战僵尸 小游戏【附源码】
Java 实现 植物大战僵尸 小游戏【附源码】
569 3
技术笔记:tcolorbox宏包简明教程
技术笔记:tcolorbox宏包简明教程
884 0
|
域名解析 Ubuntu 网络协议
如何在 Ubuntu 20.04 上安装和使用 Docker Compose
Docker Compose 是一个命令行工具,通过它你可以定义和编排多容器 Docker 应用,本文将为大家讲解如何在 Ubuntu 20.04 上安装最新版的 Docker Compose。
20407 0
如何在 Ubuntu 20.04 上安装和使用 Docker Compose