2016-03-06 78 views
0

我有一個簡單的腳本來匹配系列劇集代碼,如S01E02s09e11。這個想法是找到提供的文本中的所有插曲代碼,並創建一個包含所有發現節目的對象數組。正則表達式「gi」修飾符的組合不適用於單個單詞

我首先使用match()來獲取所有匹配代碼的數組,然後我通過代碼循環來提取季節和劇集編號。

問題是,當我用同樣的正則表達式圖案既尋找所有比賽,並提取情節細節/gi改性劑,我得到一個錯誤:Uncaught TypeError: Cannot read property '1' of null(參見控制檯輸出)。

案例1(不及格) - fiddle 1

var episodePatternGI = /s(\d{1,2})e(\d{1,2})/gi; 
var matches = 'S3E1 hehehe bla s09e12'.match(episodePatternGI); 
var episodes = []; 

matches.forEach(function(val) { 
    var ep = episodePatternGI.exec(val); 
    episodes.push({ 
    s: ep[1], 
    e: ep[2] 
    }); 
}); 

console.log(episodes); 

案例2(工作) - fiddle 2

var episodePatternGI = /s(\d{1,2})e(\d{1,2})/gi; 
var matches = 'S3E1 hehehe bla s09e12'.match(episodePatternGI); 
var episodes = []; 

var episodePatternI = /s(\d{1,2})e(\d{1,2})/i; // g modifier removed 

matches.forEach(function(val) { 
    var ep = episodePatternI.exec(val); // New pattern applied 
    episodes.push({ 
    s: ep[1], 
    e: ep[2] 
    }); 
}); 

console.log(episodes); 

正如你所看到的,在第二case我使用相同的模式,但g修改器被刪除。

爲什麼第一種情況不起作用?

回答

3

的問題是,lastIndex不會自動重置了,所以,當你調用exec的第二場比賽,也不會開始尋找在字符串的開頭,因此它不會匹配。

您可以將其設置爲0手動復位lastIndex

var episodePatternGI = /s(\d{1,2})e(\d{1,2})/gi; 
var matches = 'S3E1 hehehe bla s09e12'.match(episodePatternGI); 
var episodes = matches.map(function(val) { 
    episodePatternGI.lastIndex = 0; 
    var ep = episodePatternGI.exec(val); 
    return { 
    s: ep[1], 
    e: ep[2] 
    }; 
}); 
console.log(episodes); 

調用exec,直到到達字符串的結尾(第2個電話應該是足夠了),如圖anubhava's answer,將重置lastIndex太。

+0

準確地說我正在尋找答案。 – lesssugar

+1

噢,你打我答案。我正要提交 – 4castle

+2

儘管如此,實際上可能會使用lastIndex來獲得優勢,只需循環exec()直到它返回null。因爲目前正則表達式的使用量是其需要量的兩倍。跳過匹配數組部分。 – 4castle

2

你必須在一個循環中使用regexp.exec搶拍攝組同時使用g標誌:

var episodePatternGI = /s(\d{1,2})e(\d{1,2})/gi; 
var str = 'S3E1 hehehe bla s09e12'; 
var episodes = []; 

var m; 
while ((m = episodePatternGI.exec(str)) !== null) { 
    episodes.push({ 
     s: m[1], 
     e: m[2] 
     }); 
} 

console.log(episodes); 

Updated Fiddle

RegEx Demo(檢查代碼生成在這個環節)

+0

好的,我明白了。基本上我需要在每次迭代期間手動跟蹤'exec()'索引。有點討厭;)謝謝! – lesssugar

+0

但是,我沒有得到的東西是,在我的代碼中,我正在循環訪問代碼數組,並且分別從每個代碼**中提取季節和情節**。然而,exec()'索引在某種程度上是全球性的?帶'while'的解決方案有點不同,更簡潔。 「forEach」一個 - 不工作 - 困擾着我。 – lesssugar

+0

事實上,在這種情況下並不是真的需要,現在看到更新的答案。 – anubhava

0

如果你想將多個標誌傳遞給JS中的RegExp,你也可以這樣做:

var episodePatternGI = /s(\d{1,2})e(\d{1,2})/; 
var other = new RegExp(episodePatternGI.source, "gi"); 

這裏是一個相關主題:Changing the RegExp flags