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

标签 javascript regex

我在这里使用 AngularJS。除了“C++”之外,我匹配这些词没有问题。每次我输入“c++”作为关键字以在 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 中的 + 号用于匹配前一个字符一次或多次,然后我尝试按如下方式对 RegExp 进行硬编码来测试并且它匹配,但不是我想要的方式,因为我需要 RegExp每次我输入关键字时都会生成。

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

是否有任何方法可以使用多个关键字动态生成正则表达式来匹配包含“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++' ]

编辑

如果要创建多个 Regex,可以将 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');

关于Javascript - 使用变量 RegExp 来匹配数据数组中的多个关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28058787/

相关文章:

javascript - 输出所选按钮值或名称

javascript - 如果有两个值,则捕获 2,如果不是,则使用正则表达式捕获第一个

javascript - 从包含多维的字符串构建 JSON 对象

PHP 和正则表达式 - 可选部分

正则表达式匹配由字符分隔并由 xml 标签括起来的单词

电子邮件验证正则表达式的java代码

regex - 如何使用正则表达式获取一个单词组合的第一部分和最后一部分

javascript - IE 9 getAttribute 方法工作

javascript - 将 Javascript 变量传递到 JSON 请求

javascript - Javascript 中的字符串 <-> 数字转换