关于js正则表达式的问题。。

var str = 'For more information, see Chapter 3.4.5.1';
var re = /see (chapter \d+(\.\d)*)/i;
var found = str.match(re);

console.log(found);

为什么(\.\d)最后匹配的是.1呢,不应该是.4.5.1吗?不然说不通啊。

请大神指正。。

回复
阅读 1.8k
5 个回答

这个问题与正则表达式的贪婪模式有关。(\.\d)*这样的正则写法,默认就会采用贪婪模式,它的机制是,只要捕获到满足匹配的字符,就会接着继续往后捕获,直到不满足匹配为止,所以在匹配字符.4.5.1时,第一次会匹配到.4,第二次.5,第三次.1,以最后一次匹配到的返回。

不知道题主是不是看了MDN上的这个地方问到的,在这个例子里的输出解释里有这么一句点破了这个问题,只是它没有进一步解释贪婪模式。

// '.1' 是被'(\.\d)'捕获的最后一个值。
var re = "/see (chapter \d+((?:\.\d)*))/i";

一个点一个数字的子表达式当然只能匹配一个点加一个数字。

正则改成如下就好了:
var re = /see (chapter d+(.d)*)/ig; // g匹配所有

你注意看/see (chapter \d+(\.\d)*)/i捕获的是什么。
这里只有两个捕获组,其中(\.\d)*由于默认的贪婪匹配会匹配.4.5.1,但只会捕获最后一个匹配的项,也就是.1

1: "Chapter 3.4.5.1"
​
2: ".1"

可以再添加一个捕获组,变成/see (chapter \d+((\.\d)*))/i

1: "Chapter 3.4.5.1"
​
2: ".4.5.1"
​
3: ".1"
宣传栏