如何将字符串与Javascript中的模式数组匹配?

Posted

技术标签:

【中文标题】如何将字符串与Javascript中的模式数组匹配?【英文标题】:How to match a string against an array of pattern in Javascript? 【发布时间】:2015-06-10 14:12:12 【问题描述】:

我有两个变量:

var input = "user1@gmail.com";
var preferredPatterns = ["*@gmail.com", "*@yahoo.com", "*@live.com"];

想要将输入与首选模式数组匹配。如果任何模式匹配我必须做某些任务(在这个例子中,输入是一个明确的匹配)。如何匹配 javascript 中的模式数组?

【问题讨论】:

那些是什么模式?这些不是正则表达式。 我怎样才能把它们变成? 你需要把每一个都拿走并重写。你知道正则表达式语法吗? 更不用说,user1@gmail.com 也不是字符串。 【参考方案1】:

您可以将您的模式(如果它们是有效的正则表达式)编译成一个以提高性能:

var masterPattern = new RegExp(patterns.join('|'));

把它们放在一起:

var input = 'user1@gmail.com';
var preferredPatterns = [
  ".*@gmail.com$",
  ".*@yahoo.com$",
  ".*@live.com$"
];

var masterPattern = new RegExp(preferredPatterns.join('|'));

console.log(masterPattern.test(input));
// true

【讨论】:

这不是问题的一部分。如果你愿意,最好使用@AvinashRaj 的解决方案。根据您的原始问题,这只会非常非常快地找到任何模式是否匹配。 (手工制作masterPattern 会更快,因为您可以重构.* -- $ 位以获得更快的速度)。 但是这个显示SyntaxError: Invalid regular expression: /*@qa-server5.com$|*@qa-server4.com$/ “如果它们是有效的正则表达式”。你的不是 - * 前面需要一个句点。如果您想允许您的用户输入模式,那么您还需要一种将它们转换为有效正则表达式的方法(转义任何危险字符,并将* 转换为.*,首先)。否则,只需首先编写正确的正则表达式模式。【参考方案2】:

您需要在将变量作为正则表达式传递时使用RegExp 构造函数。

var input = 'user1@gmail.com';
var preferredPatterns = [".*@gmail\\.com$", ".*@yahoo\\.com$", ".*@live\\.com$"];
for (i=0; i < preferredPatterns.length;i++) 
  if(input.match(RegExp(preferredPatterns[i]))) 
     console.log(preferredPatterns[i])
    
    

点是正则表达式中的一个特殊元字符,可以匹配任何字符。您需要转义正则表达式中的点以匹配文字点。

正如@zerkms 所说,您也可以使用以下模式列表。

var preferredPatterns = ["@gmail\\.com$", "@yahoo\\.com$", "@live\\.com$"];

【讨论】:

你的意思是我需要给出一个精确的模式来匹配电子邮件 ID? 不,我的意思是你可以从正则表达式中删除.*,什么都不会改变。 它给出:SyntaxError: Invalid regular expression: /*@qa-server5.com$/ 在您的正则表达式中在星号前使用点。请重新检查我使用的正则表达式。 .* 将匹配包括空格在内的所有字符。所以我们应该使用非空格字符 \S 即 ["\\S*@gmail\\.com", "\\S*@yahoo\\.com", "\\S*@live\\.com"] 【参考方案3】:

试试这个辅助函数:

/**
 * Returns an integer representing the number of items in the patterns 
 * array that contain the target string text
 */
function check(str, patterns) 
   return patterns.reduce(function (previous, current) 
      return previous + (str.indexOf(current) == -1 ? 0 : 1);
    , 0);


check("user@gmail.com", ["@gmail.com", "@yahoo.com", "@live.com"]; // returns 1
check("user@live.com", ["@gmail.com", "@yahoo.com", "@live.com"]; // returns 0

【讨论】:

【参考方案4】:

如果您想要一种通用方法来匹配正则表达式列表,那么 Avinash Raj 的答案的某个版本将起作用。

基于您指定特定域的事实,您可能希望匹配any valid email address using the regex here,如果匹配,则检查该域是否是首选域。当然,有许多不同的方法可以做到这一点。这里只是一个简单的例子,在@ 上拆分并使用jQuery.inArray() 来检查该域是否是首选。

var preferredDomains = ["gmail.com", "yahoo.com", "live.com"];

function isValid(inputVal) 
    var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]0,66)\.([a-z]2,6(?:\.[a-z]2)?)$/i;

    return re.test(inputVal) && $.inArray(inputVal.split('@')[1], preferredDomains) > -1;

这里的优点是底层的正则表达式不会改变,只是更容易阅读/维护域列表。您可以调整它以捕获组中的域,而不是使用 split()。

【讨论】:

【参考方案5】:

没有正则表达式你可以做如下;

function matchPattern(xs, [y,...ys])
  
  function helper([x,...xs])
    return "*" + xs.join('') === y ? true
                                   : xs.length ? helper(xs)
                                               : false;
  
  
  return helper(xs) ? y
                    : ys.length ? matchPattern(xs,ys)
                                : "No Match..!";


var input             = "user1@gmail.com",
    preferredPatterns = ["*@yahoo.com", "*@live.com", "*@gmail.com"];
    result            = matchPattern(input, preferredPatterns);

console.log(result);

【讨论】:

【参考方案6】:
preferredPatterns.forEach(function(element, index) 
   if(input.match('/'+element) != null) 
      console.log('matching  ' + element)  
   
)

如果字符串匹配任何模式,您可以编写自定义逻辑。

【讨论】:

【参考方案7】:

您可以遍历数组,然后使用正则表达式与单个项目进行比较。

【讨论】:

以上是关于如何将字符串与Javascript中的模式数组匹配?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Javascript中用逗号分隔的值匹配数组?

如何使用与号 (&) 替换匹配模式中的字符

如何检查String是否与Groovy中的模式匹配

javascript - 在对象数组中,返回任何值与特定字符串匹配的对象

如何在javascript对象中进行模式匹配

如何将 javascript regexp 中的 Euro € 符号与八进制、十六进制或 unicode 元字符匹配?