前瞻断言与后瞻断言:JavaScript 正则表达式的秘密武器

JavaScript 中的前瞻断言(lookahead)和后瞻断言(lookbehind)相信用过的小伙伴就知道它的威力了,在一些特定的需求场景下,可以做到四两拨千斤的作用,今天让我们来盘点一下在 JavaScript 正则表达式中这两个秘密武器吧。

前瞻断言和后瞻断言,在其他语言的正则表达式中也存在,这个特性不是 JavaScript 的专属

概念定义

不管是前瞻断言还是后瞻断言,最终目的都是寻找在指定的模式(pattern)下,这个指定模式(pattern)前面或者后面的字符子串, 得到的结果永远是这些 前面或者后面的字符子串 而不是这个指定的模式(pattern)本身

前瞻或后瞻在匹配的时候不会实际匹配和捕获字符,只是检查某个位置前后是否符合指定条件,并不会改变正则的 lastIndex,在检查完之后,正则表达式的其他部分继续进行匹配。

前瞻断言

在中文互联网上 lookahead 被翻译成 前瞻断言、先行断言等

前瞻断言,是用于在检查后面的子串是否匹配某个模式, 前瞻断言包括正向前瞻负向前瞻断言

  • 正向前瞻X(?=pattern),如果 X 后面的子串符合 pattern模式, 就匹配 X。
  • 负向前瞻X(?!pattern), 如果 X 后面的子串不符合 pattern模式, 就匹配 X。

后瞻断言

在中文互联网上 lookahead 被翻译成 后瞻断言、后行断言等

后瞻断言,是用于在检查前面的子串是否匹配某个模式, 后瞻断言包括正向后瞻断言负向后瞻断言

  • 正向后瞻(?<=pattern)X,匹配 X 前面满足pattern 的子串。
  • 负向后瞻(?<!pattern)X,匹配 X 前面不满足 pattern 的子串。

这里有点需要注意的是 前瞻断言是检查后面的子串是否匹配,后瞻断言是检查前面的子串是否匹配。

这个规则感觉就是主打一个叛逆…

直接上代码

前瞻断言

  • 正向前瞻

利用正向前瞻实现金额字符串格式化为带有千分位分隔符的格式。 例如 12345, 转化为 12,345

解释一下上述的正则表达式:

  • \B:匹配非单词边界。确保逗号不会被添加在开头
  • (?=(\d{3})+(?!\d)):匹配符合右侧有一个或多个三位数字,且这些三位数字不是字符串的结尾。

这个正则同时使用了正向前瞻和负向前瞻。刚开始可能比较绕,可以看看下面的可视化原理慢慢消化一下

通过上述正则匹配到的结果,再使用 replace 方法用来替换为逗号, 即可实现金额的千分位

  • 负向前瞻

我们可以用负向前瞻来过滤一些不符合条件的字符子串。例如下面我们需要匹配出不是金额的数字。

/\d+\b(?!元)/g 正则语法的意思是 “搜索 字符中的数字,但前提是后面没有 这个字符”。

\b 是用于匹配一个单词的边界。这里使用 \b 就是为了匹配完整的数字。不然上面的测试用例里面的 15 中 的数字 1 也符合属于数字,而且1后面也没有跟 这个字符

单词边界指的是在单词字符(字母、数字或下划线)和非单词字符(如空格、标点符号或其他字符)之间的位置,同时字符串的开头或结尾也存在单词的边界。

后瞻断言

  • 正向后瞻

正向后瞻是如果当前匹配项前面有特定的匹配子串的话,当前匹配项就会被匹配,否则就跳过。

这里匹配 $ 后面的金额, 我们可以用正向后瞻断言去匹配出来。只有这个数字前面的内容满足 $ 就会匹配上,并返回到最终的结果中去。

  • 负向后瞻

如果你刚看完上面的正向后瞻的示例代码,此时你想在上面的基础上,只匹配金额前面只有一个$ 的, 这时候我们就可以用负向后瞻去做进一步约束。

这里使用 负向后瞻并不是最优解,这里只是为了做代码演示构造的场景。

可以从可视化正则里面看出,负向后瞻就是只要当前匹配项前面不是 $$的时候,才进行匹配,所以 $$34 就会被忽略掉

不过为了应用这个例子,我这里是故意这样处理的,实际上为了满足只匹配一个 $ 的金额数字的话,我们可以直接在上面的 正则加上 \s 即可, 即: /(?<=\s\$)\d+/g

兼容性

前瞻断言的兼容性是最好的,基本上是全绿的状态,直接无脑冲就行了。

当我查caniuse 的时候,有被震惊到,第一次遇到这种兼容性这么好特性。要是前端所有的标准属性有这兼容性就好了,好了,有点扯远了哈。

后瞻断言的兼容性差一些,除了在 Safari 浏览器中兼容性稍微差点,其他的都支持度很不错。

小结

相信通过上面的介绍,你已经掌握了使用 前瞻断言和后瞻断言的精髓了,相信我使用它可以让你写正则的速度嗖嗖的,下班早早的。

如果这篇文章对你有帮助,欢迎点赞👍、关注➕、转发 ✔ !

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

昇思25天学习打卡营第14天|munger85

基于MindNLPMusicGen生成自己的个性化音乐 这个所谓的个性化的音乐就是指你输入一段文字它会根据这个文字输出一段音乐这个音乐是贴近于那段文字的所以叫做文生成音乐&#xff0c; 如果网络正常的话就可以直接从下载这个模型。 那么音乐生成的有两种方式呢有两种方式&#xff…

【C++初阶】C/C++内存管理

【C初阶】C/C内存管理 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. C/C内存分布 2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3. C内存管理方式 3…

DP学习——组合模式

学而时习之&#xff0c;温故而知新。 组合模式 和代理模式相比 和代理模式相比&#xff0c;有点类似。引用类和被引用类都继承于同一个接口类。 但是感觉组合模式是对代理模式的更加丰富化&#xff08;升级版、超进化&#xff09;&#xff0c;集合化或者说聚合化。 组合模…

拉格朗日乘子法和KKT条件

拉格朗日乘子法(Lagrange Multiplier) 和 KKT(Karush-Kuhn-Tucker) 条件是求解约束优化问题的重要方法&#xff0c;在有等式约束时使用拉格朗日乘子法&#xff0c;在有不等约束时使用 KKT 条件。当然&#xff0c;这两个方法求得的结果只是必要条件&#xff0c;只有当目标函数…

ssrf复习(及ctfshow351-360)

1. SSRF 概述 服务器会根据用户提交的URL发送一个HTTP请求。使用用户指定的URL&#xff0c;Web应用可以获取图片或者文件资源等。典型的例子是百度识图功能。 如果没有对用户提交URL和远端服务器所返回的信息做合适的验证或过滤&#xff0c;就有可能存在“请求伪造"的缺陷…

C#中错误与异常处理

1、错误和异常 如果程序运行期间发生错误&#xff0c;异常就会发生。异常会中止当前的程序流&#xff0c;如果不采取措施&#xff0c;程序将停止运行。 错误和异常是两个不同的概念&#xff0c;但它们都与程序的稳定性和可维护性有关。 1.1、错误 错误通常是指编译时的语法错误…

FPGA学习笔记(一) FPGA最小系统

文章目录 前言一、FPGA最小系统总结 前言 今天学习下FPGA的最小系统一、FPGA最小系统 FPGA最小系统与STM32最小系统类似&#xff0c;由供电电源&#xff0c;时钟电路晶振&#xff0c;复位和调试接口JTAG以及FLASH配置芯片组成&#xff0c;其与STM32最大的不同之处就是必须要有…

关于Hyperf高并发性能的一些配置详解和硬件推荐

目录 工作进程的管理 自定义配置示例&#xff08;EasySwoole&#xff09;&#xff1a; 自动生成&#xff1a; 结论&#xff1a; 集群部署与协程数的关系&#xff1a; 设置 max_coroutine 的考虑因素&#xff1a; 集群部署时的配置&#xff1a; 示例配置&#xff1a; C…

链表面试练习习题集(Java)

1. 思路&#xff1a; 因为杨辉三角是由二维数组构成&#xff0c;所以要先创建一个二维数组&#xff0c;如何用顺序表表示二维数组&#xff0c;可以通过List<List<Interger>>来表示一个二维数组&#xff0c;可以这样理解&#xff1a;先创建一个一维数组List&#x…

modbus slave 设备通过 网关thingsboard-gateway 将数据上传到thingsboard云平台

搭建thingsboard物联网云平台花了大量时间&#xff0c;从小白到最后搭建成功&#xff0c;折磨了好几天&#xff0c;也感谢网友的帮助&#xff0c;提供了思路最终成功搞定&#xff0c;特此记录。 一、thingsboard环境搭建&#xff08;Ubuntu20.04LTS&#xff09; 参考官方文档&a…

java之 junit单元测试案例【经典版】

一 junit单元测试 1.1 单元测试作用 单元测试要满足AIR原则&#xff0c;即 A&#xff1a; automatic 自动化&#xff1b; I: Independent 独立性&#xff1b; R&#xff1a;Repeatable 可重复&#xff1b; 2.单元测试必须使用assert来验证 1.2 案例1 常规单元测试 1.…

PSINS工具箱函数介绍——r2d

介绍工具箱里面r2d这个小函数的作用。 程序源码 function deg r2d(rad) % Convert angle unit from radian to degree % % Prototype: deg r2d(rad) % Input: rad - angle in radian(s) % Output: deg - angle in degree(s) % % See also r2dm, r2dms, d2r, dm2r, dms2r% …

设计模式使用场景实现示例及优缺点(行为型模式——观察者模式)

阿尔法的身体内部有一个智能芯片&#xff0c;这个芯片能够根据环境和需求自动改变它的行为模式。当阿尔法需要完成不同任务时&#xff0c;它的内部状态会发生变化&#xff0c;进而改变它的行为&#xff0c;就像是它变成了另一个机器人一样。 一天&#xff0c;智能城的市长接到一…

多种方式实现 元素高度丝滑的从0-1显示出来

选择合适的方式&#xff0c;给用户更好的体验&#xff0c;多种方式实现 元素高度丝滑的从0-1显示出来。 能用 CSS 实现的动画&#xff0c;就不要采用 JS 去实现。 1、浏览器可以对CSS动画进行优化&#xff0c;其优化原理类似于requestAnimationFrame&#xff0c;会把每一帧的…

java基础学习:序列化之 - Fast serialization

在Java中&#xff0c;序列化是将对象的状态转换为字节流的过程&#xff0c;以便保存到文件、数据库或通过网络传输。Java标准库提供了java.io.Serializable接口和相应的机制来进行序列化和反序列化。然而&#xff0c;标准的Java序列化机制性能较低&#xff0c;并且生成的字节流…

appium2.0 执行脚本遇到的问题

遇到的问题&#xff1a; appium 上的日志信息&#xff1a; 配置信息 方法一 之前用1.0的时候 地址默认加的 /wd/hub 在appium2.0上&#xff0c; 服务器默认路径是 / 如果要用/wd/hub 需要通过启动服务时设置基本路径 appium --base-path/wd/hub 这样就能正常执行了 方法二…

关于Kafka的17个问题

1.Kafka 的设计时什么样的呢&#xff1f; Kafka 将消息以 topic 为单位进行归纳 将向 Kafka topic 发布消息的程序成为 producers. 将预订 topics 并消费消息的程序成为 consumer. Kafka 以集群的方式运行&#xff0c;可以由一个或多个服务组成&#xff0c;每个服务叫做一个…

前端css常用笔记

文章目录 一、样式二、vue笔记2.1、组件之间的通信2.1.1 子组件调用父组件的方法2.1.2 父组件调用子组件的方法2.1.3 孙组件调用祖父组件方法的实现 2.2、使用若依时,node_nodules越来越大的问题2.3、echart笔记 一、样式 1 文字与图标对不齐的解决方法 /**给icon加上这个样式即…

mysql的索引事务和存储引擎

一、索引 1、索引 索引的概念 &#xff1a;索引是一个排序的列表&#xff0c;在列表当中存储索引的值以及索引值对应数据所在的物理行。 索引的引用&#xff1a; 使用索引之后&#xff0c;就不需要扫描全表来定位某行的数据。 加快数据库的查询速度。 索引可以是表中的一…

ubuntu 网络 通讯学习笔记2

1.ubuntu 网络常用命令 在Ubuntu中&#xff0c;有许多网络相关的常用命令。以下是一些主要命令及其用途&#xff1a; ifconfig&#xff1a;此命令用于显示和配置网络接口信息。你可以使用它来查看IP地址、子网掩码、广播地址等。 例如&#xff1a;ifconfig 注意&#xff1a…