JavaScript对数组进行匹配

10
我想知道如何将字符串与一组正则表达式进行匹配。我知道可以通过循环数组来做到这一点。我也知道可以将所有正则表达式用|分隔并组成一个长的正则表达式来实现这一点。我希望有更高效的方法,类似于
if (string contains one of the values in array) {
例如:
string = "the word tree is in this sentence";  
array[0] = "dog";  
array[1] = "cat";  
array[2] = "bird";  
array[3] = "birds can fly";  
在上面的例子中,条件将会是假的。
然而,string = "她告诉我鸟可以飞,我表示同意了" 将会返回真。

“毛毛虫……”这个句子中包含“cat”作为另一个单词的一部分,怎么处理? - Gumbo
没问题...如果需要,我可以通过单词边界来微调正则表达式。 - Xi Vix
不确定您所说的“严格匹配”是什么意思。虽然示例已经简化,但我将使用各种正则表达式功能来将各种比较字符串与输入字符串进行匹配。例如,如果我想要隔离“cat”,我将使用\bcat\b。 - Xi Vix
@xivix:我以为你试图匹配整个单词。 - Gumbo
我不认为有任何解决方案不涉及循环整个数组。 - Liviu T.
显示剩余3条评论
4个回答

22

当您需要时,动态创建一个正则表达式(假设数组随时间变化)如何?

if( (new RegExp( '\\b' + array.join('\\b|\\b') + '\\b') ).test(string) ) {
  alert('match');
}

演示:

string = "the word tree is in this sentence"; 
var array = [];
array[0] = "dog";  
array[1] = "cat";  
array[2] = "bird";  
array[3] = "birds can fly";  

if( (new RegExp( '\\b' + array.join('\\b|\\b') + '\\b') ).test(string) ){
    alert('match');
}
else{
    alert('no match');
}


对于支持 JavaScript 版本 1.6 的浏览器,您可以使用 some() 方法

if ( array.some(function(item){return (new RegExp('\\b'+item+'\\b')).test(string);}) ) {
 alert('match');
}

演示:

string = "the word tree is in this sentence"; 
var array = [];
array[0] = "dog";  
array[1] = "tree";  
array[2] = "bird";  
array[3] = "birds can fly";  

if ( array.some(function(i){return (new RegExp('\\b'+i+'\\b')).test(string);}) ) {
 alert('match');
}


那就是我之前提到的bar方法。我知道如何使用bar设置一个长的正则表达式...但这将最终成为一个非常长的正则表达式,我希望有一种更优雅/高效的解决方案。只是想知道Javascript是否有任何内置功能来解决这个问题。 - Xi Vix
如果没有更优雅的方法,那么是通过循环数组并运行简单的正则表达式x次呢?还是将所有的正则表达式放在一个复杂的长正则表达式中? - Xi Vix
这个可行。谢谢 :) 它似乎比我之前使用的方法更有效率。 - Xi Vix
1
只是想补充一下,我的包 http://npm.im/regexr 可能会帮助简化正则表达式操作(不需要转义)。 - trusktr

5

许多年后

根据@ Gaby的回答,我需要一种检查跨来源资源共享(CORS)原点与数组中正则表达式匹配的方法:

var corsWhitelist = [/^(?:.+\.)?domain\.com/, /^(?:.+\.)?otherdomain\.com/];

var corsCheck = function(origin, callback) {
  if (corsWhitelist.some(function(item) {
    return (new RegExp(item).test(origin));
  })) {
    callback(null, true);
  } 
  else {
    callback(null, false);
  }
}

corsCheck('otherdomain.com', function(err, result) {
  console.log('CORS match for otherdomain.com: ' + result);  
});

corsCheck('forbiddendomain.com', function(err, result) {
  console.log('CORS match for forbiddendomain.com: ' + result);  
});

0

可以吗?

function checkForMatch(string,array){
    var arrKeys = array.length;
    var match = false;
    var patt;
    for(i=0; i < arrKeys; i++ ){
        patt=new RegExp(" "+array[i]+" ");
        if(patt.test(string))
           match = true;
    }
    return match;
}

string = "She told me birds can fly and I agreed"; 

var array = new Array();
array[0] = "dog";  
array[1] = "cat";  
array[2] = "bird";  
array[3] = "birds can fly";


alert(checkForMatch(string, array));

好的,谢谢你,但我已经知道如何循环遍历数组了,这就是我现在正在做的。我想Gaby上面提到的SOME函数是我能得到的最接近我所寻找的东西。 - Xi Vix

0
如果您有一个名为strings的数组,其中包含您想要匹配的字面字符串,您可以通过以下方式将它们组合成交替:
new RegExp(strings.map(
    function (x) {  // Escape special characters like '|' and '$'.
      return x.replace(/[^a-zA-Z]/g, "\\$&");
    }).join("|"))

如果你不仅有字面字符串,还想合并正则表达式,那么你可以使用http://code.google.com/p/google-code-prettify/source/browse/trunk/js-modules/combinePrefixPatterns.js
/**
 * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
 * matches the union of the sets of strings matched by the input RegExp.
 * Since it matches globally, if the input strings have a start-of-input
 * anchor (/^.../), it is ignored for the purposes of unioning.
 * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
 * @return {RegExp} a global regex.
 */

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接