9

I've two variables:

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

Want to match the input with preferred pattern array. If any of the patterns matches I've to do certain task (in this example, input is a definite match). How can I match against an array of pattern in javascript?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
fatCop
  • 2,556
  • 10
  • 35
  • 57

7 Answers7

9

You can compile your patterns (if they are valid regular expressions) into one for performance:

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

Putting it all together:

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
Amadan
  • 191,408
  • 23
  • 240
  • 301
  • That was not a part of the question. If you want that, you're better off going with @AvinashRaj's solution. This will only find whether or not any of the pattern matches, as per your original question, very very fast. (Handcrafting the `masterPattern` would be even faster, as you can refactor the `.* -- $` bit for more speed). – Amadan Apr 06 '15 at 07:21
  • but this one shows `SyntaxError: Invalid regular expression: /*@qa-server5.com$|*@qa-server4.com$/` – fatCop Apr 06 '15 at 08:36
  • "if they are valid regular expressions". Yours are not - there needs to be a period in front of the `*`. If you want to allow your users to input patterns, then you also need a method to transform them into valid regular expressions (escaping any dangerous characters, and turning `*` into `.*`, for starters). Otherwise, just write correct regular expression patterns in the first place. – Amadan Apr 06 '15 at 08:38
4

You need to use RegExp constructor while passing a variable as regex.

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])
    }
    }

Dot is a special meta-character in regex which matches any character. You need to escape the dot in the regex to match a literal dot.

As @zerkms said, you could use the below list of patterns also.

var preferredPatterns = ["@gmail\\.com$", "@yahoo\\.com$", "@live\\.com$"];
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
1

Try this helper function:

/**
 * 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
Peter
  • 3,998
  • 24
  • 33
1

If you want a general approach to matching against a list of regular expressions then some version of Avinash Raj's answer will work.

Based on the fact that you are specifying certain domains, you might want to match any valid email address using the regex here, and if it matches then check if the domain is a preferred one. There are a number of different ways you could do that of course. Here's just a simple example, splitting on the @ and using jQuery.inArray() to check if the domain is preferred.

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;
}

The advantage here is that the underlying regex doesn't change, just the much easier to read/maintain list of domains. You could tweak this to capture the domain in a group, instead of using split().

Community
  • 1
  • 1
Eric Lease
  • 4,114
  • 1
  • 29
  • 45
0
preferredPatterns.forEach(function(element, index){ 
   if(input.match('/'+element) != null){ 
      console.log('matching  ' + element)  
   }
})

you can write your custom logic if a string matches any pattern.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Nirav Shah
  • 67
  • 1
  • 2
0

No regexp you may do as follows;

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);
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Redu
  • 25,060
  • 6
  • 56
  • 76
-2

You may iterate through array and then use regex to compare with individual items.

Bhisham Balani
  • 228
  • 1
  • 4