正则表达式学习过程中的疑问

280 阅读2分钟

近期迷上了正则,疯狂练习

有几处虽然会用,但是一直搞不懂为什么?

有哪位大神能给小弟解惑么?

先介绍下几个概念:

正向零宽断言: (?=表达式),指在某个位置向右看,表示所在位置右侧必须能匹配表达式

例如: 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你

image-20211122153636827.png

正向否定零宽断言: (?!表达式)的作用是保证右边不能出现某字符。

例如: 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你

image-20211122153758728.png

反向零宽断言 : (?<=表达式),指在某个位置向左看,表示所在位置左侧必须能匹配表达式

例如: 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你

image-20211122154030509.png

反向否定零宽断言(?<!表达式),指在某个位置向左看,表示所在位置左侧不能匹配表达式

例如: 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你

image-20211122154225979.png

以上是大部分官方文档解释的4个断言,下面是我在各个论坛上看到的大神的解释


正向零宽断言: (?=p),符合p子模式前面的那个位置。换句话说是,有一个位置,紧跟其后需要满足p子模式。

'xxx_love_study_1.mp4'.replace(/(?=xxx)/g, '❤️') 
// ❤️xxx_love_study_1.mp4*

正向否定零宽断言: (?!p)反过来的意思,可以理解为(?=p)匹配到的位置之外的位置都是属于(?!p)的

'xxx_love_study_1.mp4'.replace(/(?!xxx)/g, '❤️') 
// (?=xxx)的输出
❤️xxx_love_study_1.mp4
// (?!xxx)的输出
x❤️x❤️x❤️_❤️l❤️o❤️v❤️e❤️_❤️s❤️t❤️u❤️d❤️y❤️_❤️1❤️.❤️m❤️p❤️4❤️

反向零宽断言 : (?<=p),符合p子模式后面(注意(?=p)表示的是前面)的那个位置。换句话说是,有一个位置,其前面的部分需要满足p子模式。

'xxx_love_study_1.mp4'.replace(/(?<=xxx)/g, '❤️') 
//xxx❤️_love_study_1.mp4

反向否定零宽断言(?<!p),反过来的意思,可以理解为(?<=p)匹配到的位置之外的位置都是属于(?<!p)的

'xxx_love_study_1.mp4'.replace(/(?<!xxx)/g, '❤️') 
// (?<=xxx)的输出
xxx❤️_love_study_1.mp4
// (?<!xxx)的输出
❤️x❤️x❤️x_❤️l❤️o❤️v❤️e❤️_❤️s❤️t❤️u❤️d❤️y❤️_❤️1❤️.❤️m❤️p❤️4❤️

------------------------下面开始就是疑问了------------------------

数字的千分位分割法

将123456789转化为123,456,789

let price = '123456789'
let priceReg = /(?=\d{3}$)/console.log(price.replace(priceReg, ',')) // 123456,789

他是为什么从后面开始算的位置,在我的理解里他应该是123,456789这样才对

let price = '123456789'
let priceReg1 = /(?=(\d{3})+$)/gconsole.log(price.replace(priceReg1, ',')) // ,123,456,789let priceReg2 = /(?!^)(?=(\d{3})+$)/gconsole.log(price.replace(priceReg2, ',')) // 123,456,789

这个为什么改成/(?!^)(?=(\d{3})+$)/g就能去掉首部逗号,或者说(?!^)(?=(\d{3})+$)换一下位置也不行,是固定写法么 ?

必须包含某种字符(数字、小写字母、大写字母)

(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[0-9]).{8,}/(?=.*?[a-z])/这种写法是固定写法么?这个很好用,但是一直不知道原理,这个正则应该怎么理解呢?感觉某种意义上弥补了整理没有&的尴尬(起码密码的场景里是适用)

总的来说,我搜索了很多文章,都是讲述,要么解释成断言,要么解释成表示位置,没有很好的解释,啥时候是位置,啥时候代表着断言。还有就是必须包含某位字符的,为什么可以写成这样~

这里大部分都是引用大神的语句,很少是自己写的,除了图是自己做的,下面安利一个我自己的背这些规则的一些小心得 括号里的第一个是问号都是不捕获的(?:)(?=p)(?!p)(?<=p)(?<!p),并且有规则

  1. (?:)纯不捕获,啥事没干
  2. (?<=p)(?<!p),可以理解为因为有左尖括号<,所以需要写在要匹配的左边,没有<的或者说默认是写在右边
  3. (?=p)(?!p) 这俩可以理解为,=是要匹配到的意思,!在js上是非的意思,既不要匹配的意思 按照这个规律的话,就可以很好的记住上面几个断言了,纯属个人理解,不喜勿喷,谢谢~

参考

  1. JS正则表达式完整教程(略长)
  2. 就因为这三个知识点,我彻底学废了”正则表达式“