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

正则表达式进阶学习(一):环视、捕获分组与后向引用

一、环视(零宽断言)

理论部分

环视(零宽断言)是一种用于匹配位置而非字符的正则表达式技术。它的核心特点是:不消耗字符,只检查某个位置前后是否符合特定的条件。可以理解为,环视是在匹配前“先看一看”,检查当前位置前后是否满足条件,然后再决定是否合适开始匹配。由于不消耗字符,环视可以精确控制匹配的位置,而不会干扰实际的匹配内容。

环视分为两种基本类型:顺序环视和逆序环视。

环视的基本类型
环视类型描述正则表达式
肯定顺序环视在当前位置的后边(顺序),必须有条件给出的字符串(?=expression)
否定顺序环视在当前位置的后边(顺序),不能有条件给出的字符串(?!expression)
肯定逆序环视在当前位置的前边(逆序),必须有条件给出的字符串(?<=expression)
否定逆序环视在当前位置的前边(逆序),不能有条件给出的字符串(?<!expression)
环视的优势

环视技术在处理复杂文本时有显著优势:

  • 精确控制位置:环视不消耗字符,能精确控制匹配的位置,避免不必要的字符干扰。
  • 构建复杂模式:通过组合顺序和逆序环视,可以在特定上下文中进行复杂的匹配操作。
  • 提高效率:环视避免了不必要的字符匹配,优化了正则表达式的执行效率,尤其适用于大规模文本处理。

实际应用

假设我们从 ifconfig 命令的输出中提取 IP 地址。我们可以使用以下正则表达式:

(?<=inet )(.*?)(?= netmask)

解释:

  • (?<=inet ):肯定逆序环视,确保匹配的前面是 "inet "。
  • (.*?):非贪婪匹配任意字符,直到遇到下一个模式。
  • (?= netmask):肯定顺序环视,确保匹配的后面是 " netmask"。

该正则表达式能够准确地提取 IP 地址,而不包括 “inet” 和 “netmask”。这种匹配方式不仅高效,而且非常灵活,适用于各种类似的上下文提取任务。


二、捕获分组与后向引用

理论部分

1. 分组的概念

分组是正则表达式中的一种机制,通过使用圆括号 () 将一个子表达式封装成一个整体,从而能够在匹配过程中独立地引用或操作该部分内容。简而言之,分组让我们能够捕获并单独处理表达式中的特定部分。

理解分组最好的方式是通过示例。假设我们想匹配两个连续出现的“hello”字符串,而不仅仅是“helloo”。通过正则表达式 hello{2},我们只能匹配到“helloo”,因为 {2} 只影响其前面的字符。但是,如果我们希望匹配“hellohello”,就需要将“hello”当作一个整体来看待。这时,我们可以用分组来实现:

(hello){2}

在这个例子中,(hello) 表示“hello”作为一个分组,而 {2} 则表示这个分组要连续出现两次。这样,正则表达式就能够匹配到“hellohello”。

2. 分组嵌套

分组不仅可以是独立的子表达式,还可以通过嵌套来构造更复杂的匹配模式。例如:

(ab(ef){2})

在这个例子中:

  • 最外层的圆括号 () 将整个“ab(ef){2}”作为一个分组。
  • 内部的 (ef) 表示“ef”应该连续出现两次。

这条正则表达式会匹配到“abefef”。分组的嵌套使我们能够精细控制每一部分的匹配。

3. 后向引用的概念

后向引用是指在正则表达式中,引用之前定义的捕获分组内容。通过后向引用,我们可以在后续的匹配中使用已匹配的部分内容。

举个例子,我们有以下两行文本:

Hello world
Hiiii world

如果我们用正则表达式 H.{4},它会匹配“Hello”和“Hiiii”两行,因为 .{4} 可以匹配任意四个字符。

但假设我们有个新需求:只匹配“world”前后相同的单词。也就是说,要求“world”前后都是“Hello”或“Hiiii”。为了满足这个需求,我们可以使用后向引用:

(H.{4})\s+world\s+\1

在这个正则中:

  • (H.{4}) 是第一个分组,匹配“Hello”或“Hiiii”。
  • \1 是后向引用,它引用第一个分组的内容,要求“world”后面跟随相同的单词。

这样,只有在“world”前后单词一致时,匹配才会成功。

4. 后向引用的具体操作

当正则表达式中有多个分组时,后向引用会按分组的顺序引用相应的内容。例如:

(a(bc){2})

这里有两个分组:

  • a 是第一个分组,匹配字母 “a”。
  • (bc) 是第二个分组,匹配“bc”并要求其连续出现两次。

如果后续的正则表达式中使用 \1\2,它们将分别引用第一个和第二个分组的内容。

5. 嵌套分组与后向引用

在实际应用中,分组可以嵌套,因此后向引用的编号也会随之变化。例如:

((ab)(ef){2})

这条正则有三个分组:

  1. ((ab)(ef){2}):最外层的分组,匹配“abefef”。
  2. (ab):第二个分组,匹配“ab”。
  3. (ef):第三个分组,匹配“ef”并要求连续出现两次。

在这种情况下,\1 引用整个“abefef”,\2 引用“ab”,而\3 引用“ef”。

实际应用

1. 匹配重复出现的字符串

假设我们需要匹配一行文本中重复出现的字符串,并且中间可以有任意数量的空格。可以使用以下正则表达式:

([a-z]+)\s+\b\1\b

解释:

  • ([a-z]+):捕获一个由小写字母组成的单词(第一个分组)。
  • \s+:匹配一个或多个空白字符(空格或制表符)。
  • \b:单词边界,确保匹配的是独立的单词。
  • \1:后向引用,确保匹配的第二个单词与第一个单词完全相同。

这个正则表达式用于匹配两个相同的小写单词,中间由空格或其他空白字符分隔。

2. 匹配多次重复的字符串

如果需要匹配一个模式多次出现,可以使用以下正则表达式:

([a-z]+)([ \t]+\<\1\>)+

解释:

  • ([a-z]+):匹配并捕获一个由小写字母组成的单词。
  • [ \t]:匹配一个或多个空白字符。
  • \<\1\>:后向引用第一个捕获分组。

通过这种方式,可以匹配在文本中多次重复的特定字符串,并支持更复杂的匹配任务。


总结

环视(零宽断言)和捕获分组是正则表达式中两种至关重要的技术,它们各自在不同的应用场景中提供了精确控制和高效匹配的能力。

  • 环视 通过不消耗字符的方式,能够精确地限定匹配位置,避免了不必要的字符干扰,特别适用于需要根据上下文条件来提取信息的场景。顺序环视和逆序环视的结合使得我们能够在不修改文本的前提下,只关注特定位置前后是否符合某些模式,从而提升了匹配的灵活性和准确性。

  • 捕获分组 通过将正则表达式中的部分内容封装在分组内,使得我们可以在后续的匹配中引用这些内容。这种方式不仅有助于构建更复杂的匹配模式,还能够有效地进行重复模式的匹配,特别是在处理多次出现的相同数据时,极大地提高了正则表达式的应用范围和效率。

总的来说,环视和捕获分组是正则表达式中不可或缺的工具,它们让我们能够精确提取目标内容,避免冗余匹配,从而在数据提取、文本处理、日志分析等领域发挥重要作用。通过合理运用这两种技术,可以大大提升正则表达式的性能和准确度,使其在各种复杂的文本匹配任务中得以高效执行。

相关文章:

正则表达式进阶学习(一):环视、捕获分组与后向引用

一、环视&#xff08;零宽断言&#xff09; 理论部分 环视&#xff08;零宽断言&#xff09;是一种用于匹配位置而非字符的正则表达式技术。它的核心特点是&#xff1a;不消耗字符&#xff0c;只检查某个位置前后是否符合特定的条件。可以理解为&#xff0c;环视是在匹配前“…...

《Vue3 七》插槽 Slot

插槽可以让组件的使用者来决定组件中的某一块区域到底存放什么元素和内容。 使用插槽&#xff1a; 插槽的使用过程其实就是抽取共性、预留不同。将共同的元素、内容依然留在组件内进行封装&#xff1b;将不同的元素使用 slot 作为占位&#xff0c;让外部决定到底显示什么样的…...

【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 一、线性表的基本概念 二、初始化线性表 三、销毁线性表 四、判定是否为空表 五、求线性表的长度 六、输出线性表 七、求线性表中某个数据元素值 八、按元素值查找 九、插入数据元素 十、删除数据元素 测试说明 通关代码 测…...

Linux C/C++编程-获得套接字地址、主机名称和主机信息

【图书推荐】《Linux C与C一线开发实践&#xff08;第2版&#xff09;》_linux c与c一线开发实践pdf-CSDN博客《Linux C与C一线开发实践&#xff08;第2版&#xff09;&#xff08;Linux技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com…...

USB kbtab linux 驱动代码

#include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> #include <linux/usb/input.h> #include <asm/unaligned.h> /* Pressure-threshold modules param code from */MODULE_AUTHOR(“xxx”); MODULE_DESCRIPTION(“…...

力扣 跳跃游戏

每次更新目标位置时&#xff0c;实际上是在做一个局部的最优选择&#xff0c;选择跳跃能够到达当前目标位置的最远位置。因为每次更新目标位置时&#xff0c;都是基于当前能跳跃到的最远位置&#xff0c;因此最终的结果是全局最优的。 题目 从前往后遍历&#xff0c;更新可以到…...

使用npm 插件[mmdc]将.mmd时序图转换为图片

使用npm 插件[mmdc]将.mmd时序图转换为图片 1. 安装 mmdc2. 转换为图片 可以使用 mmdc &#xff08;Mermaid CLI&#xff09;这个工具来将 .mmd 时序图&#xff08;Mermaid语法描述的时序图&#xff09;转换为图片&#xff0c;以下是使用步骤&#xff1a; 1. 安装 mmdc 确保…...

ffmpeg 常用命令

更详细请参考ffmpeg手册&#xff0c;下载ffmpegrelease版后在doc中就有&#xff0c;主页面。video filter 参考ffmpeg-filters.html -version -formats -demuxers -protocols -muxers -filters -devices —pix_fmts -codecs -sample_fmts -decoders -layouts -encoders -colors…...

从入门到实战:C 语言 strlen 函数通关指南

文章目录 一、strlen函数简介1. 函数构成2. 参数说明3. 使用示例 二、模拟实现strlen函数&#xff08;从新手角度逐步升级改进&#xff09;1. 基础版本&#xff08;利用循环计数&#xff09;2. 改进版本&#xff08;利用指针相减&#xff09;3. 递归版本&#xff08;利用递归思…...

npm install --global windows-build-tools --save 失败

注意以下点 为啥下载windows-build-tools&#xff0c;是因为node-sass4.14.1 一直下载不成功&#xff0c;提示python2 没有安装&#xff0c;最终要安装这个&#xff0c;但是安装这个又失败&#xff0c;主要有以下几个要注意的 1、node 版本 14.21.3 不能太高 2、管理员运行 …...

十种基础排序算法(C语言实现,带源码)(有具体排序例子,适合学习理解)

学习了十种常见的排序方法&#xff0c;此文章针对所学的排序方法进行整理&#xff08;通过C语言完成排序&#xff09;。 参考内容&#xff1a; https://blog.csdn.net/mwj327720862/article/details/80498455 https://www.runoob.com/w3cnote/ten-sorting-algorithm.html 1. 冒…...

基于fMRI数据计算脑脊液(CSF)与全脑BOLD信号的时间耦合分析

一、前言 笔者之前的文章《基于Dpabi和spm12的脑脊液(csf)分割和提取笔记》,介绍了如何从普通的fMRI数据中提取CSF信号。首先是基础的预处理,包括时间层校正、头动校正,再加上0.01-0.1Hz的带通滤波。接着用SPM12分割出CSF区域,设置一个比较严格的0.9阈值,确保提取的真是…...

实现websocket心跳检测,断线重连机制

WebSocket基础 WebSocket概念 WebSocket是一种革命性的 全双工通信协议 &#xff0c;构建在TCP之上&#xff0c;旨在简化客户端与服务器之间的数据交换过程。通过单次握手建立持久连接&#xff0c;WebSocket实现了真正的双向实时通信&#xff0c;显著提高了交互效率。这一特性…...

ComfyUI节点安装笔记

AI高速发展&#xff0c;版本更新相当快&#xff08;11月25日才安装的版本v.0.3.4&#xff0c;27日版本就已经更新到v.0.3.5了&#xff09;&#xff0c;在遇到问题&#xff0c;找到问题原因所在的过程中&#xff0c;ComfyUI版本、python版本、节点对环境版本的依赖&#xff0c;本…...

深度学习,训练集准确率高,但验证集准确率一直不上升,很低的问题

在训练过程中&#xff0c;训练集的准确率稳步上升&#xff0c;但是验证集的准确率一直在40%左右徘徊&#xff0c;从网上搜索可能的原因有&#xff1a; 1、学习率太小&#xff0c;陷入局部最优。 2、数据量太小&#xff08;4000多条数据&#xff0c;应该还可以吧&#xff09; …...

【C语言程序设计——选择结构程序设计】求输入的日期是该年的第几天(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 1、switch 结构基本语法 2、示例代码及解释 3、使用注意事项 4、判断闰年的条件 编程要求 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;编写程序实现&#xff1a;从键盘上输入一个年月日&#xff08;以空格或回车…...

Lumos学习王佩丰Excel二十四讲系列完结

“Lumos学习王佩丰Excel二十四讲系列”是一套完整的Excel教程&#xff0c;涵盖了从基础到高级的各种知识和技能。是我亲自一个个码出来的教程哇&#xff01;&#xff01;&#xff01; 一、课程概览 该教程共分为24讲&#xff0c;每一讲都围绕Excel的一个核心主题进行深入讲解…...

前后端规约

文章目录 引言I 【强制】前后端交互的 API请求内容响应体响应码II 【推荐】MVC响应体III【参考】IV 其他引言 服务器内部重定向必须使用 forward;外部重定向地址必须使用 URL 统一代理模块生成,否则会因线上采用 HTTPS 协议而导致浏览器提示“不安全”,并且还会带来 URL 维护…...

【数据可视化】数据可视化看板需求梳理模板(含示例)

一、模板 设计一个数据可视化看板需要从多个方面梳理需求&#xff0c;以确保看板能够有效地传达信息并满足用户的需求。以下是一些关键方面&#xff1a; 1.目标和受众 ● 明确目标&#xff1a;确定看板的主要目的&#xff0c;例如监控业务指标、分析市场趋势、展示项目进度等…...

CArray原理是什么,通过示例来展示如何使用?

CArray是MFC&#xff08;Microsoft Foundation Class&#xff09;库中的一个模板类&#xff0c;用于实现动态数组的功能。它类似于C语言中的数组&#xff0c;但具有自动增长和缩小的能力&#xff0c;从而方便管理动态数据。以下是对CArray原理的解析以及一个使用示例。 CArray…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...