正则表达式进阶学习(一):环视、捕获分组与后向引用
一、环视(零宽断言)
理论部分
环视(零宽断言)是一种用于匹配位置而非字符的正则表达式技术。它的核心特点是:不消耗字符,只检查某个位置前后是否符合特定的条件。可以理解为,环视是在匹配前“先看一看”,检查当前位置前后是否满足条件,然后再决定是否合适开始匹配。由于不消耗字符,环视可以精确控制匹配的位置,而不会干扰实际的匹配内容。
环视分为两种基本类型:顺序环视和逆序环视。
环视的基本类型
| 环视类型 | 描述 | 正则表达式 |
|---|---|---|
| 肯定顺序环视 | 在当前位置的后边(顺序),必须有条件给出的字符串 | (?=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})
这条正则有三个分组:
((ab)(ef){2}):最外层的分组,匹配“abefef”。(ab):第二个分组,匹配“ab”。(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\>:后向引用第一个捕获分组。
通过这种方式,可以匹配在文本中多次重复的特定字符串,并支持更复杂的匹配任务。
总结
环视(零宽断言)和捕获分组是正则表达式中两种至关重要的技术,它们各自在不同的应用场景中提供了精确控制和高效匹配的能力。
-
环视 通过不消耗字符的方式,能够精确地限定匹配位置,避免了不必要的字符干扰,特别适用于需要根据上下文条件来提取信息的场景。顺序环视和逆序环视的结合使得我们能够在不修改文本的前提下,只关注特定位置前后是否符合某些模式,从而提升了匹配的灵活性和准确性。
-
捕获分组 通过将正则表达式中的部分内容封装在分组内,使得我们可以在后续的匹配中引用这些内容。这种方式不仅有助于构建更复杂的匹配模式,还能够有效地进行重复模式的匹配,特别是在处理多次出现的相同数据时,极大地提高了正则表达式的应用范围和效率。
总的来说,环视和捕获分组是正则表达式中不可或缺的工具,它们让我们能够精确提取目标内容,避免冗余匹配,从而在数据提取、文本处理、日志分析等领域发挥重要作用。通过合理运用这两种技术,可以大大提升正则表达式的性能和准确度,使其在各种复杂的文本匹配任务中得以高效执行。
相关文章:
正则表达式进阶学习(一):环视、捕获分组与后向引用
一、环视(零宽断言) 理论部分 环视(零宽断言)是一种用于匹配位置而非字符的正则表达式技术。它的核心特点是:不消耗字符,只检查某个位置前后是否符合特定的条件。可以理解为,环视是在匹配前“…...
《Vue3 七》插槽 Slot
插槽可以让组件的使用者来决定组件中的某一块区域到底存放什么元素和内容。 使用插槽: 插槽的使用过程其实就是抽取共性、预留不同。将共同的元素、内容依然留在组件内进行封装;将不同的元素使用 slot 作为占位,让外部决定到底显示什么样的…...
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
目录😋 任务描述 相关知识 一、线性表的基本概念 二、初始化线性表 三、销毁线性表 四、判定是否为空表 五、求线性表的长度 六、输出线性表 七、求线性表中某个数据元素值 八、按元素值查找 九、插入数据元素 十、删除数据元素 测试说明 通关代码 测…...
Linux C/C++编程-获得套接字地址、主机名称和主机信息
【图书推荐】《Linux C与C一线开发实践(第2版)》_linux c与c一线开发实践pdf-CSDN博客《Linux C与C一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (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(“…...
力扣 跳跃游戏
每次更新目标位置时,实际上是在做一个局部的最优选择,选择跳跃能够到达当前目标位置的最远位置。因为每次更新目标位置时,都是基于当前能跳跃到的最远位置,因此最终的结果是全局最优的。 题目 从前往后遍历,更新可以到…...
使用npm 插件[mmdc]将.mmd时序图转换为图片
使用npm 插件[mmdc]将.mmd时序图转换为图片 1. 安装 mmdc2. 转换为图片 可以使用 mmdc (Mermaid CLI)这个工具来将 .mmd 时序图(Mermaid语法描述的时序图)转换为图片,以下是使用步骤: 1. 安装 mmdc 确保…...
ffmpeg 常用命令
更详细请参考ffmpeg手册,下载ffmpegrelease版后在doc中就有,主页面。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函数(从新手角度逐步升级改进)1. 基础版本(利用循环计数)2. 改进版本(利用指针相减)3. 递归版本(利用递归思…...
npm install --global windows-build-tools --save 失败
注意以下点 为啥下载windows-build-tools,是因为node-sass4.14.1 一直下载不成功,提示python2 没有安装,最终要安装这个,但是安装这个又失败,主要有以下几个要注意的 1、node 版本 14.21.3 不能太高 2、管理员运行 …...
十种基础排序算法(C语言实现,带源码)(有具体排序例子,适合学习理解)
学习了十种常见的排序方法,此文章针对所学的排序方法进行整理(通过C语言完成排序)。 参考内容: 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是一种革命性的 全双工通信协议 ,构建在TCP之上,旨在简化客户端与服务器之间的数据交换过程。通过单次握手建立持久连接,WebSocket实现了真正的双向实时通信,显著提高了交互效率。这一特性…...
ComfyUI节点安装笔记
AI高速发展,版本更新相当快(11月25日才安装的版本v.0.3.4,27日版本就已经更新到v.0.3.5了),在遇到问题,找到问题原因所在的过程中,ComfyUI版本、python版本、节点对环境版本的依赖,本…...
深度学习,训练集准确率高,但验证集准确率一直不上升,很低的问题
在训练过程中,训练集的准确率稳步上升,但是验证集的准确率一直在40%左右徘徊,从网上搜索可能的原因有: 1、学习率太小,陷入局部最优。 2、数据量太小(4000多条数据,应该还可以吧) …...
【C语言程序设计——选择结构程序设计】求输入的日期是该年的第几天(头歌实践教学平台习题)【合集】
目录😋 任务描述 相关知识 1、switch 结构基本语法 2、示例代码及解释 3、使用注意事项 4、判断闰年的条件 编程要求 测试说明 通关代码 测试结果 任务描述 本关任务:编写程序实现:从键盘上输入一个年月日(以空格或回车…...
Lumos学习王佩丰Excel二十四讲系列完结
“Lumos学习王佩丰Excel二十四讲系列”是一套完整的Excel教程,涵盖了从基础到高级的各种知识和技能。是我亲自一个个码出来的教程哇!!! 一、课程概览 该教程共分为24讲,每一讲都围绕Excel的一个核心主题进行深入讲解…...
前后端规约
文章目录 引言I 【强制】前后端交互的 API请求内容响应体响应码II 【推荐】MVC响应体III【参考】IV 其他引言 服务器内部重定向必须使用 forward;外部重定向地址必须使用 URL 统一代理模块生成,否则会因线上采用 HTTPS 协议而导致浏览器提示“不安全”,并且还会带来 URL 维护…...
【数据可视化】数据可视化看板需求梳理模板(含示例)
一、模板 设计一个数据可视化看板需要从多个方面梳理需求,以确保看板能够有效地传达信息并满足用户的需求。以下是一些关键方面: 1.目标和受众 ● 明确目标:确定看板的主要目的,例如监控业务指标、分析市场趋势、展示项目进度等…...
CArray原理是什么,通过示例来展示如何使用?
CArray是MFC(Microsoft Foundation Class)库中的一个模板类,用于实现动态数组的功能。它类似于C语言中的数组,但具有自动增长和缩小的能力,从而方便管理动态数据。以下是对CArray原理的解析以及一个使用示例。 CArray…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
在树莓派上添加音频输入设备的几种方法
在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
