2009-05-09 134 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