2017-07-17 62 views
-1

我有一個字符串數組,我試圖過濾包含重複字符的字符串數組。然而,我不明白的兩件奇怪的事情正在發生。這裏是我的代碼:重複字母的正則表達式是否爲false?

var array = ["aba", "aab", "baa"]; 

var pattern = /(\D)\1+/gi; 

var filteredArr = array.filter(function(element){ 
    console.log(element); 
    console.log(pattern.test(element)); 
    return pattern.test(element) != true; 
}); 

console.log(filteredArr); 

一些奇怪的事情發生。在過濾器函數中,我測試了正則表達式是真還是假,並且它是應該的。

pattern.test("aba") = false; 
pattern.test("aab") = true; 
pattern.test("baa") = true; 

但是,如果我測試它們之外的功能,「baa」似乎返回false ......這是不是正確的?

console.log(pattern.test("aba")); //returns false 
console.log(pattern.test("aab")); //returns true 
console.log(pattern.test("baa")); //returns false 

對下一個奇怪的事情。過濾器函數應該返回不通過(即返回false)過濾器測試的元素。我的預期產出將是:

filteredArr = ["aba"]; 

然而,該代碼是這樣的,我的輸出是:

filteredArr = ["aba", "aab", "baa"]; 

什麼是更奇怪的是,如果我改變過濾函數返回的元素DO傳遞(即返回true)的測試,預期的輸出將是:

filteredArr = ["aab", "baa"]; 

然而,我接收輸出是一個空數組:

filteredArr = []; 

我很困惑。我的正則表達式是錯誤的,還是我可能嘗試了一些過濾器函數無法做到的事情?這裏是所有的代碼的小提琴:

My fiddle

+0

請剛剛發佈了一個新問題之前做一些研究。 – Mritunjay

+0

刪除'g'標誌。 –

回答

2

你看到的奇怪的行爲是g修改的結果。對test的每個呼叫都在推進該模式的lastIndex屬性,這使得在test()的下一個呼叫在字符串的稍後時間點開始。

這裏的MDN description of the lastIndex property

此屬性設置僅在正則表達式實例使用的 「G」標誌,以表明全局搜索。以下規則適用:

  • 如果lastIndex大於字符串,test()exec()失敗的長度,然後lastIndex設置爲0
  • 如果lastIndex等於字符串的長度,並且如果正則表達式與空字符串匹配,則正則表達式 與從lastIndex開始的輸入匹配。
  • 如果lastIndex等於字符串的長度,並且如果正則表達式與空字符串不匹配,則表示規則 表達式與輸入不匹配,而lastIndex重置爲0
  • 否則,lastIndex被設置爲最近一次匹配後的下一個位置。

您可以通過添加console.log(pattern.lastIndex);filter驗證這一點:

var array = ["aba", "aab", "baa"]; 
 

 
var pattern = /(\D)\1+/gi; 
 

 
var filteredArr = array.filter(function(element){ 
 
    var test = pattern.test(element); 
 
    console.log(element + ": " + test); 
 
    console.log(pattern.lastIndex); 
 
    return test; 
 
}); 
 

 
console.log(filteredArr);

要解決你的代碼,從正則表達式中刪除g標誌。

0

您正在使用全局正則表達式,其中.test存在問題。

考慮下面的開發者控制檯跟蹤

$ var pattern = /(\D)\1+/gi; 
undefined 
$ pattern.lastIndex 
0 
$ pattern.test('xx') 
true 
$ pattern.lastIndex 
2 
$ pattern.test('xx') 
false 
$ pattern.lastIndex 
0 

你正在運行到的問題是,RegExp s的的g標誌簡歷在lastIndex檢查,因此,如果您連續檢查相同的字符串兩次,你會得到不同的結果。

您可以手動重置pattern.lastIndex = 0或使用非全局RegExp

0

這是一個工作示例。

var array = ["aba", "aab", "baa","bba","bab"]; 
 

 

 
var filteredArr = array.filter(function(element){ 
 
    console.log(element); 
 
    //note that a constant is used instead of the var 
 
    var t = /(\D)\1+?/gi.test(element); 
 
    console.log(t); 
 
    return !t; 
 
}); 
 

 
console.log(filteredArr);

與您的代碼的問題是在這裏:

使用試驗(+),只要你想知道的模式是否在 字符串(類似於字符串發現.prototype.search()方法,區別在於 test()返回一個布爾值,而search()返回索引(如果找不到則返回 -1);有關更多信息(但執行較慢),請使用exec()方法(類似於String.prototype.match()方法)。作爲 與exec()(或與其組合),在相同的全局正則表達式實例上多次調用test()將會超過前一匹配

RegExp.prototype.test()