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

我有两个变量:

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

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

【问题讨论】:

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

标签: javascript arrays regex


【解决方案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】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-28
            • 2012-04-26
            • 2020-01-03
            • 2014-02-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多