Javascript - 使用变量 RegExp 匹配数据数组中的多个关键字

Javascript - Use variable RegExp to match multiple keywords in an array of data

本文关键字:数组 关键字 数据 变量 RegExp Javascript      更新时间:2023-09-26

我在这里使用AngularJS。除了"C++"之外,我没有问题匹配这些词。每次我输入"c ++"作为关键字以在 Javascript 中生成正则表达式并运行匹配时,我在控制台中收到错误,如下所示:

语法错误:正则表达式无效:/(''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++"的数据数组?

考虑到您将在 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');

你必须转义特殊字符

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)";
}

类似的东西。请注意,此解决方案非常冗长,并且特殊字符列表非常有限。