我在这里使用AngularJS。除了“C ++”之外,我没有问题匹配这些词。每次我输入“c ++”作为关键字在Javascript中生成RegExp并运行匹配时,我在控制台中得到错误如下:
SyntaxError:无效的正则表达式:/(\ bc ++ \ b)/:无需重复
代码段如下:
$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中的+符号用于匹配前一个字符的一次或多次,然后我尝试对RegExp进行硬编码,如下所示进行测试并匹配,但不是我想要的方式,因为我需要RegExp每次我输入关键字时都会生成。
$scope.regExp = /c\+\++/i
有没有办法动态生成一个包含多个关键字的RegExp,以匹配包含“c ++”的数据数组?
答案 0 :(得分: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++' ]
修改强>
如果要创建多个Regex,可以将ip.replace
和new 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');
答案 1 :(得分: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)";
}
这样的事情。请注意,此解决方案非常详细,特殊字符列表非常有限。