正则学习(三)-正则中不得不说的捕获和反向引用
2023-12-25 10:51:59一. 子表达式
在正则表达式中,被一对圆括号括起来的内容,这个内容,被称为子表达式。
比如:
const regex = /(\d)hello/;
这个正则表达式中 \d 被称为子表达式。
二. 捕获组
在正则表达式中,子表达式匹配到相应的内容时,系统会自动捕获到这个行为,然后把子表达式匹配的内容放入系统的缓存中,我们把这个过程称为捕获。
正则捕获后我们可以使用RegExp.$1获取捕获的第一个内容,$2表示捕获的第二个内容,以此类推,也可以从match,exec等js方法返回值中获取。
例如:
console.log("1hello2".match(/(\d)hello(\d)/));
console.log(RegExp.$1); // "1"
console.log(RegExp.$2); // "2"

需注意:捕获顺序是从外往内,从左往右的一个个顺序捕获。
console.log("1hello2".match(/((\d)hello(\d))/));
console.log(RegExp.$1); // 1hello2
console.log(RegExp.$2); // 1
console.log(RegExp.$3); // 2

三. 命名捕获组
从上面图中,可以看到match的返回值中有一个groups属性,这个就是存储命名捕获组的。
如果你想自命名,那么请使用?<name>。除了用groups对象,我们还可以在replace方法中使用$
const res = "1hello2".match(
/(?<allHello>(?<helloBefore>\d)hello(?<helloAfter>\d))/
);
console.log(res);
console.log(res.groups);

四. 非捕获
一对圆括号括起来,里面的内容匹配时会被捕获,但是当我们想要这个内容非捕获时,就可以使用(?: )。
"1hello2".match(/(?:(?:\d)hello(?:\d))/);

从上图中,可以看到,目前已经没有捕获组内容。
五. 反向引用
在正则表达式中,我们可以使用 \k
(k >= 1,代表捕获内容的第几个,从1开始)来获取缓冲区的内容,这个被称为反向引用。
"1hello1".match(/(\d)hello(\1)/g);

如果对命名捕获组反向引用时,又该如何呢?
用法:k<name>
"1hello1".match(/(?<start>\d)hello(k<start>)/g);
