老姚小册中没有提到的两小点

560 阅读2分钟

不得不说,老姚的小册写的特别好,使我半天基本上就掌握了正则。

但是使用过程中发现了两点问题

分组与“或”逻辑

要匹配的数据:

__*数据*__
_**据数**_
***aaa***

我遇到了如上情况,在学习老姚的小册后,写出了以下正则

/(?:(\*)(\*)(\*)|(_)(\*)(\*)|(\*)(_)(_))[^\*\_]+\3\2\1/

问题在于,分组括号的序列“\1”、“\2”、“\3”到底是运行时还是编译时决定的?

如果是运行时会造成匹配或逻辑第一个情况后才决定序列号,最后以上表达式是成立的,但这是理想的

经过测试是编译就决定了,所以上述表达式是错误的

所以最后我把表达式修改成了以下:

/(?:(_)(\*)(\*)[^\*_]+\3\2\1)|(?:(_)(_)(_)[^\*_]+\6\5\4)|(?:(\*)(_)(_)[^\*_]+\9\8\7)/

断言与捕捉数据

要匹配的数据

/home/.../module1/index.js
/home/.../module2/index.js
/home/.../aaa/index.js

我想拿到“module1”、“module2”、“aaa”,怎么拿

大家的第一反应肯定是split('/')+[length-2]或者其他api组合,但是正则完全可以胜任。

/(?<=(\\|\/))[^\\/]+(?=((\\|\/)index\.js))/

会发现一个新东西(?<=),这是es6新增的后行断言语法,所以老的引擎都不支持

但是重点不是语法问题,而是捕捉

我们要获取的肯定是module1这种,怎么过一次性取出来呢?

如果要匹配的话要根据特征前面有“/”,后面有“/index.js”,但是匹配的话会携带,我们的想法肯定是要将他们除去,可能会想到“^”,但是只能支持单字符

这时,应该想到断言,在用断言的时候会发现,这种语法并不会将匹配的内容附加进来,比如:

ab
  • 捕获a后的b,在正则表达式的意义上为b的前一个位置是a,属于后行断言。

    const reg=/(?<=a)b/    //b
    
  • 捕获b前的a,在正则表达式的意义上为a的后一个位置是b,属于先行断言。

    const reg=/a(?=b)/     //a
    

利用这点我们可以一次性提取出来”module1“、“module2“、“aaa”

没了,如果觉得有用请别忘记点赞~

有疑问下方评论