2009-05-09 138 views
60

为什么Javascript子匹配在设置g修饰符时停止工作?JavaScript正则表达式和子匹配

var text = 'test test test test'; 

var result = text.match(/t(e)(s)t/); 
// Result: ["test", "e", "s"] 

以上优良工程,result[1]"e"result[2]"s"

var result = text.match(/t(e)(s)t/g); 
// Result: ["test", "test", "test", "test"] 

上面的内容忽略了我的捕获组。以下是唯一有效的解决方案吗?

var result = text.match(/test/g); 
for (var i in result) { 
    console.log(result[i].match(/t(e)(s)t/)); 
} 
/* Result: 
["test", "e", "s"] 
["test", "e", "s"] 
["test", "e", "s"] 
["test", "e", "s"] 
*/ 

回答

91

使用Stringmatch()函数不会返回捕获组,如果全球修改设置,因为你发现了。

在这种情况下,您需要使用RegExp对象并调用其exec()函数。 Stringmatch()RegExpexec()函数几乎相同...除了这些情况。如果设置了全局修饰符,则正常match()函数将不返回捕获的组,而RegExpexec()函数将会返回。 (注意到here,在其他地方。)

另一个抓记住的是,exec()不会在一个大阵列,它一直返回比赛,直到它用完了,在这种情况下,它会返回null返回比赛。

因此,举例来说,你可以做这样的事情:

var pattern = /t(e)(s)t/g; // Alternatively, "new RegExp('t(e)(s)t', 'g');" 
var match;  

while (match = pattern.exec(text)) { 
    // Do something with the match (["test", "e", "s"]) here... 
} 

另一个要注意的是,RegExp.prototype.exec()RegExp.prototype.test()执行所提供的字符串的正则表达式,返回的第一个结果。每个顺序调用将根据字符串中的当前位置逐步更新结果集RegExp.prototype.lastIndex

下面是一个例子: //记住在示例和模式中有4个匹配。 lastIndex的从0开始

pattern.test(text); // pattern.lastIndex = 4 
pattern.test(text); // pattern.lastIndex = 9 
pattern.exec(text); // pattern.lastIndex = 14 
pattern.exec(text); // pattern.lastIndex = 19 

// if we were to call pattern.exec(text) again it would return null and reset the pattern.lastIndex to 0 
while (var match = pattern.exec(text)) { 
    // never gets run because we already traversed the string 
    console.log(match); 
} 

pattern.test(text); // pattern.lastIndex = 4 
pattern.test(text); // pattern.lastIndex = 9 

// however we can reset the lastIndex and it will give us the ability to traverse the string from the start again or any specific position in the string 
pattern.lastIndex = 0; 

while (var match = pattern.exec(text)) { 
    // outputs all matches 
    console.log(match); 
} 

你可以找到关于如何使用RegExp对象on the MDN(具体而言,这里是为the exec() function的文档)的信息。

+3

使用exec似乎不听g修饰符,但它支持子匹配/组。所以结果将是第一个匹配(它基本上忽略了g修饰符) – 2009-05-09 21:03:37

+0

添加了一个关于这个的澄清 - 你必须重复调用exec()来获得多个匹配。 – hbw 2009-05-09 21:05:52

+2

不是最优雅的解决方案。 我有些期望的输出是这样的: [ \t [ “测试”, “E”, “S”], \t [ “测试”, “E”, “S”], \t [” test“,”e“,”s“], \t [”test“,”e“,”s“] – 2009-05-09 21:13:01