正则表达式(6):分组与后向引用

正则表达式(6):分组与后向引用

      • 总结

本博文转载自

在本博客中,”正则表达式”为一系列文章,如果你想要从头学习怎样在Linux中使用正则,可以参考此系列文章,直达链接如下:

在Linux中使用正则表达式

“正则”系列的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。

前文中,已经总结了正则表达式中的常用字符、次数匹配、位置匹配等,这篇文章中,我们来了解一下正则中的”分组”与”后向引用”。

什么是分组?什么是后向引用?我们慢慢聊。

先来说说什么是分组。

算了,思考了半天,我也不知道从何说起,先看个示例吧,根据示例去描述反而更加清晰,示例如下。

在这里插入图片描述

上述示例中,我们使用到了之前所了解到的”连续次数匹配”,”{2}”表示其前面的字符连续出现的2次,即可被匹配到。

但是,正如上图所示,”\{2\}”所影响的字符只是其前面的单个字符,也就是上例中的字母o

所以,上例中,helloo被匹配到了,hellooo也被匹配到了,因为”hell”字符串后面的确出现了2次字母o

但是,如果我们想要从上例中的文本中找出,2次连续出现的hello字符串,该怎么办呢?

正如你所看到的,”hello\{2\}”并不能表示”hellohello”,它只能表示”helloo”,那么,我们该怎么办呢?

这个时候,我们就需要用到”分组”,将”hello”当做一个”分组”,当做一个”整体”,才可以达到我们的目的,示例如下

在这里插入图片描述

正如上图所示,”\(hello\)”表示将hello字符串当做一个整体,所以,”\{2\}”所影响的字符就是前面的”hello字符串”(这个整体)。

所以,”\(hello\)\{2\}”这个正则表达式就表示hello字符串连续出现两次,也就是”hellohello”

没错,”\( \)”就表示分组。

“\( \)”表示将其中的内容看做一个分组,看做一个整体。

分组还可以嵌套,什么意思呢?我们来看一个例子。

在这里插入图片描述

上图中的正则表达式猛一看有些复杂,但是我们一点一点的拆开来看,就比较容易理解了,没错,我们先按照上图所示,将”红线部分”与”蓝线部分”拆成两部分

蓝线部分为”\{2\}”,表示之前的字符连续出现两次

红线部分为”\(ab\(ef\)\{2\}\)”,可以看到,红线部分的两侧正好由”\( \)”组成,由此可见,红线部分应该作为一个整体,应该作为一个分组被操作,再结合之前的蓝线部分,即可得知,红线部分应该作为一个整体连续出现两次。

那么,我们把红线部分最外侧的”\( \)”去掉,红线部分内侧的正则为”ab\(ef\)\{2\}”,可以看到,红线部分内侧的正则中还有一组分组符号,就是”(ef)”,这个分组符号把ef当做了一个整体,所以,”ab\(ef\)\{2\}”表示字符串ab后面跟随了2个连续出现的ef,那么,”ab\(ef\)\{2\}”就表示字符串”abefef”。

逆推回去,我们把红线内侧的正则替换为”abefef”,于是,上例中的正则就表示”\(abefef\)\{2\}”,最终如上图所示,2次连续出现的abefef被匹配到了。

上例中,红线部分一共包含两个分组符号,最外侧的”\( \)”中又包含了另一个”\( \)”,这就是分组符号的嵌套。

我想,我应该说清楚了。

那么,我们再来聊聊什么是后向引用。

之所以先介绍分组,是因为后向引用是以分组为前提的,如果想要实现后向引用,则必须先进行分组。

那么”后向引用”是什么意思呢?

如果直接放出概念,我不容易描述,你也不容易理解,我们还是先来看个小例子吧,示例文件如下。

在这里插入图片描述

如果我们想要使用正则去匹配上述示例中的两行文本,我们改怎么办呢?

我们可以使用如下正则表达式去匹配。

在这里插入图片描述

“H.\{4\}”表示大写字母H的后面跟随了4个任意字符,其中”.”表示任意单个字符,我们在前文中已经举例演示过,此处不再赘述。

所以,”H.\{4\}”既可以匹配到Hello,也可以匹配到Hiiii,那么,上述两行文本都被匹配到了。

此时,我们修改一下示例文件,在示例文件中再添加一行测试文本,修改后的测试文件内容如下

在这里插入图片描述
如上图所示,我们添加了一行文本,这行文本以Hello开头,以Hiiii结尾。

我们使用刚才的正则,能够匹配到这一行新添加的文本吗,我们来试试。

在这里插入图片描述

可以看到,新添加的一行文本也被匹配到了,因为”H.\{4\}”表示大写字母H的后面跟随了4个任意字符,最后一行也满足条件,所以也被匹配到了。

但是此刻,我有了新需求~~

我只想从上例中找出”world”前后单词相同的那些行,换句话说就是,world之前的单词是Hello,world之后的单词也要是Hello,world之前的单词是Hiiii,world之后的单词也要是Hiiii,只有这种行满足条件。

上例中第三行则不满足条件,因为上例的第三行中,world之前的单词是Hello,而world之后的单词是Hiiii,前后不一致,所以不满足我的条件。

那么我该怎么办呢?之前的正则肯定不行,因为之前的正则也能够将上例中的第三行匹配到。

这个时候,就需要用到”后向引用”,示例如下。

在这里插入图片描述

可以看到,使用上述正则,即可达到我们的目的,只有world前后的单词完全相同时,才会被匹配到。

那么,上例中的正则是什么意思呢?我们仍然拆成两部分来介绍,以便我们理解。

上例的红线部分为:“\(H.\{4\}\)”`
上例的蓝线部分为:”\1″

红线部分的正则与之前示例中的正则只有一点点区别,就是在原来的基础之上添加了分组,将”H.\{4\}”变成了”\(H.\{4\}\)”,但是它的大概含义并没有改变,”\(H.\{4\}\)”表示大写字母H的后面跟随了4个任意字符,并且字母H与后面的4个字符将作为一个整体。那么,为什么要在原来的基础上添加分组呢?这是因为,如果想要实现后向应用,则必须以分组为前提,现在我们暂且不纠结这一点,之后回过头来看,就会明白。

蓝色部分的正则为”\1″,它有什么含义呢?

“\1″表示整个正则中第1个分组中的正则所匹配到的结果,这样说可能不容易理解,我们用大白话说一遍。

在上例中,整个正则中只出现了1个分组,就是”\(H.\{4\}\)”,当它与示例文件中的第一行文本进行匹配时,会匹配到Hello字符串,这时,”\1″就表示Hello字符串。

当正则”\(H.\{4\}\)”与示例文件中的第二行文本进行匹配时,会匹配到Hiiii字符串,这时,”\1″就表示Hiiii字符串。

也就是说,”\1″必须与整个正则中第1个分组中的正则(也就是红色部分的正则)所匹配到的结果相同。

换句话说就是,”\1″引用了整个正则中第1个分组中的正则(也就是红色部分的正则)所匹配到的结果。

如果你还没有懂,看图理解吧。

在这里插入图片描述

现在回头想想,你知道为什么必须为”H.\{4\}”添加分组了吗?因为,当我们为”H.\{4\}”添加了分组以后,”H.\{4\}”就变成了整个正则中第1个分组中的正则,当”H.\{4\}”匹配到的结果为Hello时,”\1″就引用了Hello,当”H.\{4\}”匹配到的结果为Hiiii时,”\1″就引用了Hiiii。

这就是所谓的”后向引用”。

上述描述看一遍可能不容易立马理解,可以重复仔细的多看几遍,慢慢就会理解了。

聪明如你,一定想到了。

“\1″表示引用整个正则中第1个分组中的正则所匹配到的结果,那么,”\2″呢?没错,正如你所想。

“\2″表示引用整个正则中第2个分组中的正则所匹配到的结果

示例如下

在这里插入图片描述

如上图所示,”\2″引用了上图中”绿线部分的正则”所匹配到的结果,而上图中”绿线部分的正则”就是”整个正则表达式中第2个分组中的正则”。

那么,以此类推,”\3″、”\4″、”\5″、”\6″所表达的意思就不言而喻了。

再次强调,使用后向引用的前提是将需要引用的部分分组。

不过,当分组嵌套时,我们应该怎样区分哪个分组是第1个分组,哪个分组是第2个分组呢?

我们通过一个小示例,即可明白,为了尽量简化整个正则,我们直接将一些字符分组即可,示例如下。

在这里插入图片描述
上述正则表达式中,一共出现了两个分组,一个分组嵌套着另一个分组。

在这里插入图片描述

可以从上图中看出,红色标注的符号是一对分组符号,蓝色标注的符号是一对分组符号,红色分组嵌套这蓝色分组。

虽然上例中没有使用到”后向引用”,但是,当我们需要使用”后向引用”时,这两个分组哪个才是第1个分组,哪个是第2个分组呢?

当我们需要使用后向引用时,红色分组为第1个分组,蓝色分组为第2个分组。

换句话说就是,当使用后向引用时,”\1″引用的是红色分组所匹配的结果,”\2″引用的是蓝色分组所匹配的结果。

为什么呢?原因就是,分组的顺序取决于分组符号的左侧部分的顺序,如下图所示

在这里插入图片描述

由于红色分组的左侧部分排在最前面,所以红色分组是整个正则中的第1个分组。

由于蓝色分组的左侧部分排在第2位,所以蓝色分组是整个正则中的第2个分组。

注意:排序时也仅仅按照分组符号的左侧部分排序,分组符号的右侧部分不算在排序范围内。

好了,”分组”与”后向引用”就总结到这里,我想我应该说明白了,描述起来好费力~~~希望能够帮到你。

之前说过,在Linux中,正则表达式分为基础正则表达式与扩展正则表达式。

而我们之前所描述的符号都属于基本正则表达式。

在以后的文章中,我们会接触到扩展正则表达式,但是不用害怕,它们的用法都是相似的,而且写法也差不多,学会基本正则表达式以后,再学习扩展正则表达式,几乎不会费力。

总结


为了方便以后回顾,我们将今天了解到的只是进行总结。

\( \) 表示分组,我们可以将其中的内容当做一个整体,分组可以嵌套。

\(ab\) 表示将ab当做一个整体去处理。

\1 表示引用整个表达式中第1个分组中的正则匹配到的结果。

\2 表示引用整个表达式中第2个分组中的正则匹配到的结果。

这篇文章就总结到这里,希望能够帮助到你~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/245392.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Stm32-F407】Keil uVision5 下新建工程

①双击鼠标左键打开Keil uVision5,选择 Project 下的 New uVision Project ; ②在期望的文件夹下创建一个工程,并按如下要求操作; ③添加文件类型,按如下要求操作 ④如有需要可添加相关启动文件在工程文件夹下并添加到…

RNN介绍及Pytorch源码解析

介绍一下RNN模型的结构以及源码,用作自己复习的材料。 RNN模型所对应的源码在:\PyTorch\Lib\site-packages\torch\nn\modules\RNN.py文件中。 RNN的模型图如下: 源码注释中写道,RNN的数学公式: 表示在时刻的隐藏状态…

渗透测试框架——Cobalt Strike

渗透测试框架——Cobalt Strike Cobalt Strike是一款非常成熟的渗透测试框架。Cobalt Strike在3.0版本之前是基于Metasploit框架工作的,可以使用Metasploit的漏洞库。从3.0版本开始,Cobalt Strike不再使用Metasploit的漏洞库,成为一个独立的…

每日好题:原来你也玩三国杀(DP动态规划)

I - 原来你也玩三国杀 Description 小 Q 最近听说 “很多” acmer 都爱上了一款游戏《三国杀》。因为小 Q 是一个初学者,所以想自己先偷偷学习一下,然后惊艳所有人。但又因为小 Q 不屑于使用一般的武将,因为他觉得唯有操作型武将才能显得自…

性能监控软件:优化系统运行的得力助手

随着科技的飞速发展,企业和组织对于其信息技术基础设施的性能要求也愈发提高。为了确保系统能够高效稳定地运行,性能监控软件成为不可或缺的工具。本文将探讨性能监控软件的主要作用,以及它们在提升系统性能和稳定性方面的关键作用。 1. 实时…

学习MS Dynamics AX 2012编程开发 1. 了解Dynamics AX 2012

在本章中,您将了解开发环境的结构以及Microsoft Dynamics AX中的开发人员可以访问哪些工具。在本书的第一步演练之后,您将很容易理解著名的Hello World代码,您将知道应用程序对象树中的不同节点代表什么。 以下是您将在本章中学习的一些主题…

10、ble_mesh_node服务节点示例

1。手机APP选择名字,点击provisioner App keys,识别,配网。 2。初始化流程, board_init()初始化IO,初始化存储, bluetooth_init()蓝牙初始化,ble_mesh_get_dev_uuid(dev_uuid)蓝牙组网初始化, 3、蓝牙组网初…

MyBatis缓存机制流程分析

前言 在进行分析之前,建议快速浏览之前写的理解MyBatis原理、思想,这样更容易阅读、理解本篇内容。 验证一级缓存 MyBatis的缓存有两级,一级缓存默认开启,二级缓存需要手动开启。 重复读取跑缓存 可以看到,第二次…

[MySQL] MySQL中的索引

文章目录 一、初识索引 1、1 索引的概念 1、2 索引案例 二、认识磁盘 2、1 磁盘结构 2、2 操作系统与磁盘的数据交互 2、3 磁盘随机访问与连续访问 2、4 MySQL与磁盘的数据交互 三、索引的理解 3、1 建立测试表 3、2 为何MySQL与磁盘IO交互是 Page 3、3 理解Page 3、3、1 页目录…

【WSL】Windows下的Linux子系统使用方法指南

▒ 目录 ▒ 🛫 导读需求开发环境 1️⃣ WSL安装启用或关闭windows功能安装分发命令行启动Linux 2️⃣ WSL 的基本命令显示帮助列出可用的 Linux 发行版列出已安装的 Linux 发行版检查 WSL 版本更新 WSL通过 PowerShell 或 CMD 运行特定的 Linux 发行版关闭WSL全部服…

Centos7防火墙及端口开启

1、防火墙 1.1、查看防火墙是否开启 systemctl status firewalld 1.2、开启防火墙 firewall-cmd --list-ports 1.3、重启防火墙 firewall-cmd --reload 2、端口 2.1、查看所有已开启的端口号 firewall-cmd --list-ports 2.2、手动开启端口 启动防火墙后,默认没有开…

智能优化算法应用:基于共生生物算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于共生生物算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于共生生物算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.共生生物算法4.实验参数设定5.算法结果6.…

1、springboot项目运行报错

问题1:获取不到配置文件的参数 我的配置文件获取的参数如下: public class Configures{Value("${configmdm.apk.apkName}")private static String apkName;private void setApkName(String apkName) {Configures.apkName apkName;}private …

【亚马逊云科技】通过高性能低延迟对象存储 S3实现网站资源托管

本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 亚马逊云科技开发者社区, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道 文章目录 前言1 S3 介绍1.1 优点 2 使用步骤2.1 注册账户2.2 创建存储桶2.2.1 打开控制…

C/C++常见面试题(二)

接前面C/C常见面试题(一),继续巩固 目录 1 sizeof和strlen的区别 2 宏定义的陷阱 3 不使用sizeof计算出类型或者变量所占的内存的字节数 4 给定一个数判断是否其是2的N次幂 5 C/C打印所在文件、行号、函数、日期,时间、遵循的…

每日分享,以元旦为题的诗词

元旦佳节即将来临,相信大家都会在朋友圈表达一下自己的情感,不管大家以前是怎么表达的,今天小编给你分享几首以元旦为题的几首诗,喜欢的朋友可以自取,想要更多免费的诗词,请自行百度或小程序搜索&#xff1…

智能守护,数据安全稳中求胜!上海迅软DSE助力家具家电行业引领潮流!

随着中国经济的蓬勃发展,家具家电企业正迎来“精品制造”的时代,业内竞争日益激烈。为了提升产品竞争力、扩大市场占有率,企业亟需加强对自主品牌的安全建设,确保品牌的自主知识产权、产品生产资料以及销售信息等核心数据不受泄漏…

C++二维数组(2)

图形相似度 题目描述: 给出两幅相同大小的黑白图像(用0-1矩阵)表示,求它们的相似度。 说明:若两幅图像在相同位置上的像素点颜色相同,则称它们在该位置具有相同的像素点。 两幅图像的相似度定义为相同像素…

为什么阿里云不能免费帮用户无限抵御DDoS攻击

DDoS防御需要成本,其中最大的成本就是带宽费用。带宽是阿里云向电信、联通、移动等运营商购买,运营商计算带宽费用时不会把DDoS攻击流量清洗掉,而是直接收取阿里云的带宽费用。阿里云云盾在控制成本的情况下会尽量为阿里云用户免费防御 DDoS攻…

PXI总线测试模块-6935B 微波本振源

6935B 微波本振源 PXI总线测试模块 650MHz~10GHz 01 产品综述 6935B微波本振源采用3U 2槽PXIe结构形式,具有频率范围宽、相位噪声低、频率分辨力高、体积小等优点。其优异的性能使其可适用于通信以及导航设备等众多领域产品的研发、生产、检测与维护中&#xff0c…