2015-01-21 86 views
0

我在這裏使用AngularJS。除了「C++」以外,我沒有任何問題匹配。每次我在「C++」類型的關鍵字生成JavaScript中的正則表達式和運行的配套,我得到了控制檯如下錯誤:Javascript - 使用變量RegExp匹配數據數組中的多個關鍵字

SyntaxError: Invalid regular expression: /(\bc++\b)/: Nothing to repeat

的代碼片段如下:

$scope.data = [ 
 
    {'title': 'Blue Java Programming Book'}, 
 
    {'title': 'Red C++ Programming Book'}, 
 
    {'title': 'Javascript Dummies Guide'} 
 
    ]; 
 

 
$scope.submit = function() { 
 
    $scope.length = $scope.keywords.split(" ").length; 
 
    $scope.keywordsArray = $scope.keywords.split(" "); 
 

 
    $scope.pattern = ""; 
 
    for (var y = 0; y < $scope.length; y++) { 
 
    $scope.pattern += "(?=.*?\\b" + $scope.keywordsArray[y] + "\\b)"; 
 
    } 
 
    $scope.pattern+=".*"; 
 
    $scope.patt = new RegExp($scope.pattern, "i"); 
 
    for (var x = 0; x < $scope.data.length; x++) { 
 
    console.log("Match [" + x + "] " + $scope.patt.test($scope.data[x].description)); 
 
    } 
 

 
}
<input type="text" ng-model="keywords"></input> 
 
<button ng-click="submit()">Submit</button>

據我所知,在正則表達式的+號是匹配前面的字符一次或多次,然後,我嘗試硬編碼爲下面的正則表達式來測試和匹配,但不是我想要的,因爲我需要的方式RegExp是gen每次我輸入關鍵字時都會精心製作。

$scope.regExp = /c\+\++/i

是否有任何方式來生成與多個關鍵字飛一個RegExp以匹配數據的陣列,其包括「C++」?

+0

我不是100%肯定你的問題是什麼,但你也可以代表C++爲C [\ +] {2} – 2015-01-21 02:53:57

+0

你想生成的正則表達式'$ scope.data'中的每個關鍵字? – 2015-01-21 03:17:26

+0

@AnuragPeshne我想根據輸入的關鍵字生成正則表達式,然後在$ scope.data中搜索匹配的關鍵字 – imationyj 2015-01-21 04:31:41

回答

1

考慮,你會在VAR ip收集輸入,你可以試試這個:如果你想創建多個正則表達式

rrexp = new RegExp('[\\+|\\^|\\-|\\||\\?|\\*|\\{|\\}|\\$]','g'); 
//rrexp contains all the special characters which need to be escaped 

ip = 'c++'; 
var escapedExp = ip.replace(rrexp, function(fs, matched){ 
    return '\\'+fs; 
}); 
/* 
ip.replace will replace special characters in the 'ip' to be replaced by escaped version of them. 
For Eg. + will replaced \\+. Thus 'c++' becomes 'c\\+\\+' 
*/ 

var regEx = new RegExp(escapedExp, 'gi'); 
// this creates Regular Expression based on the ip which matches all exp and is case insensitive. 

q = 'Red C++ Programming Book'; 
q.match(regEx); //this should output: [ 'C++' ] 

編輯

,你可以把ip.replacenew Regex在循環。有時像

inputs = ['c++', 'simpleExp', 'complex$one']; 
var escapedExp, regEx; 
regexList = []; 
inputs.forEach(function(ip) { 
    escapedExp = ip.replace(rrexp, function(fs, matched){ 
    return '\\'+fs; 
    }); 
    regEx = new RegExp(escapedExp, 'gi'); 
    regexList.push(regEx); 
}); 
//regexList will contain all the Regex based on inputs 

編輯2: \b單詞邊界無法企及的特殊字符的話。

單詞邊界聲明,位置前面是一個單詞字符,後面跟一個單詞,後面跟一個單詞字符,前面沒有一個單詞。因此除'_'之外的所有特殊字符都不會被\b識別。

我可以建議一個黑客:你需要找出關鍵字中的特殊字符出現的位置,然後根據它添加\b。如果關鍵字末尾有特殊字符,我們不能在關鍵字開始後類似地添加\b。如果兩端都有正常字符,那麼我們可以在兩端添加\b

這是我會怎麼做:

noBAtStart = false; 
noBAtEnd = false; 
var escapedExp = ip.replace(rrexp, function(matched, offset) { 
    if(offset == 0) 
    noBAtStart = true; 
    if(offset == ip.length - 1) 
    noBAtEnd = true; 
    return '\\' + matched; 
}); 

if(!noBAtStart) 
    escapedExp = '\\b' + escapedExp; 
if(!noBAtEnd) 
    escapedExp = escapedExp + '\\b'; 

var regEx = new RegExp(escapedExp, 'gi'); 
+0

如果我想搜索多個關鍵字,該怎麼辦?這意味着我的IP將是一個關鍵字數組,以匹配一個句子。順便說一句,我不明白'函數(fs,匹配){return'\\'+ fs;});'你能解釋一下嗎?謝謝。 – imationyj 2015-01-21 05:17:06

+0

我試過你的代碼,結果與@Crazysheep發佈的結果相同。我在他的回答下的評論中解釋了這個問題。 – imationyj 2015-01-21 05:33:29

+0

@imationyj我在代碼中添加了註釋,希望能解釋這些代碼行的功能。 查看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace以瞭解匿名函數接受哪些參數。 – 2015-01-21 05:34:28

0

你必須躲避特殊字符

for (var y = 0; y < $scope.length; y++) { 
    var specialRegexChars = ["*", "+", ".", "(", ")", "{", "}"]; 

    // For each character in the word, prepend it with \ if it's in our list of special characters 
    var chars = $scope.keywordsArray[y].split(""); 
    for (var i = 0; i < chars.length; i++) { 
    if (specialRegexChars.indexOf(chars[i]) !== -1) { 
     chars[i] = "\\" + chars[i]; 
    } 
    } 
    $scope.pattern += "(?=.*?\\b" + chars.join("") + "\\b)"; 
} 

類似的東西。請注意,這個解決方案非常詳細,特殊字符列表非常有限。

+0

關鍵字「C++」的結果是「/(?=.*?\bc\+ \ + \ b)。* /我'對嗎?它在我執行'.test(「C++」)'函數後返回false。 – imationyj 2015-01-21 04:52:00

+0

當我在匹配「C++」的時候,在模式的後面添加一個'\ b'時似乎不起作用。如果我刪除了它,那麼當將「C++」與「C++編程書」匹配時它會返回true,但它不會得到我想要的結果ie:只有在通過「C++編程書」進行搜索時關鍵字是「編程」如果關鍵字是「program」或​​「programmin」,NOT NOT返回true – imationyj 2015-01-21 05:32:10

相關問題