2014-06-06 61 views
3

我有一個非常strage問題:JavaScript RegExp不能使用兩次?

var cat = [ { slug: "test/foo", id: 1}, { slug: "test/bar", id: 1}]; 
var searchreg = new RegExp("test","g"); 

cat.forEach(function(item){ 
    if(searchreg.test(item.slug)){ 
    console.log(item); 
    } 
}); 

這應該打印我的兩個項目進行的「貓」。但我只得到第一個。如果我添加更多的項目,我只會得到每一個第二(從第一個開始)。

我得到它與沃金:

var cat = [ { slug: "test/foo", id: 1}, { slug: "test/bar", id: 1}]; 

cat.forEach(function(item){ 
    var searchreg = new RegExp("test","g"); 
    if(searchreg.test(item.slug)){ 
    console.log(item); 
    } 
}); 

但我不明白爲什麼不工作(鉻) - 任何人主意?

+1

FWIW,一個更簡單,更直接的方式來創建該正則表達式是'var searchreg =/test/g;'(或者當然,根據我的回答,省略'g')。另外值得一提的是你實際上並不需要regex,if(item.slug.indexOf(「test」)!== -1)'也可以。 –

回答

6

這是因爲g(「全球」)標誌。當您使用g標誌時,RegExp實例具有狀態:他們記得他們看到的最後一個匹配的位置,因此它們可以從該點繼續(例如,如果您正在循環中使用它們)。 (是的,這不是最好的設計。)所以第一次在字符串中找到test(注意它不在字符串的結尾處);第二次,它試圖找到test繼續在前一個位置的字符串中,當然不會找到它。第三次,因爲它知道上次輸入已經用完了,所以它再次查看輸入。

在你的情況,因爲你並不需要比一審進一步搜索時,只要將g標誌:

var searchreg = /test/; // That's a regex literal, basically: ... = new RegEx("test") 

另外,還可以通過分配0lastIndex屬性重置:

searchreg.lastIndex = 0; 
if (searchreg.test(item.slug)) 

或者說,在這具體使用的情況下,你不需要正則表達式的所有:

if (item.slug.indexOf("test") !== -1) { 
    // It has "test" in the slug 
} 
+2

您可以通過將其lastIndex屬性設置爲0來「重置」一個全局正則表達式。然後,您應該再次質疑爲什麼您首先使用全局正則表達式...... – MaxArt

+1

哦,謝謝 - 明確表示: g-flag :-)我真的不需要/ g,它只是從另一個代碼複製粘貼。所以我刪除/克,它的作品完美! 關於indexOf:我有一個更復雜的正則表達式,我只是選擇「test」作爲一個簡單的例子。 – mdunisch

+0

有用的詳細答案+1 :) – zx81