首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用变量RegExp匹配数据数组中的多个关键字

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

Stack Overflow用户
提问于 2015-01-21 02:48:51
回答 2查看 532关注 0票数 0

我在这里使用AngularJS。除了"C++“之外,我对匹配这些词没有任何问题。每次输入"c++“作为关键字在Javascript中生成RegExp并运行匹配时,我都会在控制台中得到如下错误:

SyntaxError:无效正则表达式: /(\bc++\b)/:无重复

代码片段如下所示:

代码语言:javascript
复制
$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));
  }

}
代码语言:javascript
复制
<input type="text" ng-model="keywords"></input>
<button ng-click="submit()">Submit</button>

据我所知,RegExp中的+符号是为了匹配前一个字符的一次或多次,然后我尝试按下面的方式对RegExp进行硬编码以测试和匹配,但不是我想要的方式,因为每次我输入关键字时都需要生成RegExp。

代码语言:javascript
复制
$scope.regExp = /c\+\++/i

是否有任何方法可以动态生成包含多个关键字的RegExp,以匹配包含"c++“的数据数组?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-21 05:00:15

考虑到您将收集var ip中的输入,您可以尝试如下:

代码语言:javascript
复制
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放在一个循环中。有时就像

代码语言:javascript
复制
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

我会这样做:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2015-01-21 03:10:31

你必须转义特殊的字符

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28058787

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档