正则表达式中?=和?:和?!的理解

正则表达式中?=和?:和?!的理解

要理解?=和?!,首先需要理解前瞻,后顾,负前瞻,负后顾四个概念:

// 前瞻:
exp1(?=exp2) 查找exp2前面的exp1
// 后顾:
(?<=exp2)exp1 查找exp2后面的exp1
// 负前瞻:
exp1(?!exp2) 查找后面不是exp2的exp1
// 负后顾:
(?<!exp2)exp1 查找前面不是exp2的exp1

举例:

'中国人'.replace(/(?<=中国)人/, 'rr') // 匹配中国人中的人,将其替换为rr,结果为 中国rr
'法国人'.replace(/(?<=中国)人/, 'rr') // 结果为 法国人,因为人前面不是中国,所以无法匹配到

要理解?:则需要理解捕获分组和非捕获分组的概念

   ()表示捕获分组,()会把每个分组里的匹配的值保存起来,使用$n(n是一个数字,表示第n个捕获组的内容)
(?:)表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来

举例:

// 数字格式化 1,123,000
'1234567890'.replace(/\B(?=(?:\d{3})+(?!\d))/g, ',') // 结果:1,234,567,890,匹配的是后面是3*n个数字的非单词边界(\B)

版权声明:本文为 CSDN 博主「这个昵称没有被占用吧」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/csm0912/article/details/81206848

个人理解

上面的知识点又叫环视,查找的东西不会占据位置,只是查找配位的位置

(?=…) 肯定顺序环视,子表达式能匹配右侧的文本;

(?!..) 否定顺序环视,子表达式不能匹配右侧的文本;

(?<=…) 肯定逆序环视,子表达式能匹配左侧的文本;

(?<!..) 否定逆序环视,子表达式不能匹配左侧的文本.

let int = 1215553
console.log(int.toString().replace(/(?=((?!\b)\d{3})+$)/g, ',')) 
//1,215,553

   上述代码的功能是实现数字千分位的的功能,核心在于正则表达式,以下是我的理解。

    首先,从最内层解析。先看第一个括号 (?!\b) ,这个代表 “查找右面不是\b的xx” (注:\b => 匹配单词边界)。然后看第二个括号 ((?!\b)\d{3}) ,这句话的意思是,匹配右面不是单词边界的并且有3个的数字位置。最后看 (?=((?!\b)\d{3})+$) ,这句话的意思是,从头开始环视,找到右边不是单词边界并且有 多组的 连续3个数字而且结尾的位置。

上面案例分析过程

o代表位置
第一次查找
  ‘o1215553’ ,这个位置的右边是个单词边界,所以匹配不成功,向后继续匹配。 ‘1o215553’,这个位置的右边不是单词边界,满足第一个条件,继续检查是否满足条件,右边是一串数字,存在连续的3个数字,满足第二个条件,继续检测。‘1215o553’,因为+的原因继续进行第二次前两个条件的判断,发现还是满足,并且这时候已经到达符合前两个匹配条件结尾位置(不一定是数字结尾)。最后查看符合,当前位置是不是数字结尾,如果是,则’1o215553’此位置符合要求。

第二次查找
  ‘12o15553’,从此位置开始第二次查找。按照同样的规则检测,发现它不能满足第三个匹配条件,此时最后符合前两个条件的匹配位置在这里:’12155o53‘,这个位置不是数字结尾的位置,所以匹配失败。开始下一次查找,这时候开始的位置是:’121o5553‘
。以此类推到数字结尾

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值