77

Is there a way in JavaScript to get Boolean value for a match of the string against the array of regular expressions?

The example would be (where the 'if' statement is representing what I'm trying to achieve):

var thisExpressions = [ '/something/', '/something_else/', '/and_something_else/'];
var thisString = 'else';

if (matchInArray(thisString, thisExpressions)) {

} 
2
  • Are you looking for a match against all expressions (AND), or any of the expressions (OR)? Commented Apr 14, 2012 at 9:53
  • With jquery you can use jQuery.inArray(); Commented Apr 14, 2012 at 9:56

11 Answers 11

141
+50

Using a more functional approach, you can implement the match with a one-liner using an array function:

ECMAScript 6:

const regexList = [/apple/, /pear/];
const text = "banana pear";
const isMatch = regexList.some(rx => rx.test(text));

ECMAScript 5:

var regexList = [/apple/, /pear/];
var text = "banana pear";
var isMatch = regexList.some(function(rx) { return rx.test(text); });
Sign up to request clarification or add additional context in comments.

3 Comments

Also worth mentioning the filter method for Arrays, which is often useful and is used in the same way.
Also, check out .every if you want it to match all in the array vs .some which returns true if it matches any in the array.
This should be the accepted answer for modern JavaScript.
21

http://jsfiddle.net/9nyhh/1/

var thisExpressions = [/something/, /something_else/, /and_something_else/];
var thisExpressions2 = [/else/, /something_else/, /and_something_else/];
var thisString = 'else';

function matchInArray(string, expressions) {

    var len = expressions.length,
        i = 0;

    for (; i < len; i++) {
        if (string.match(expressions[i])) {
            return true;
        }
    }

    return false;

};

setTimeout(function() {
    console.log(matchInArray(thisString, thisExpressions));
    console.log(matchInArray(thisString, thisExpressions2));
}, 200)​

4 Comments

Why not strip the res variable out entirely, return true in your if statement and return false at the end. Then it will quit on finding the first match.
Also i'd use expressions[i].test(string) rather than string.match()
Although this code may answer the question, providing additional context regarding why and/or how it answers the question would significantly improve its long-term value. Please edit your answer to add some explanation.
What about let's say I wanted the index of the value that was matched?
6

You could use .test() which returns a boolean value when is find what your looking for in another string:

var thisExpressions = [ '/something/', '/something_else/', '/and_something_else/'];
var thisString = new RegExp('\\b' + 'else' + '\\b', 'i');
var FoundIt = thisString.test(thisExpressions);  
if (FoundIt) { /* DO STUFF */ }

6 Comments

RegExp.prototype.test() cannot be used with an Array. It takes a string. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
@gdibble it will work, because test it calls toString on the supplied argument, which, for array, will join(). Probably not advisable though!
Example: /monkey/.test({ toString : () => "monkey" }) // true
@Likwid_T - what does '\\b' mean ? I know that 'i' means case insensitive, but I could not find online what \\b means. Also, why do you have it twice?
@GK79 a \b is a word-boundary - such that you could match /\broller\b/ in just the word 'roller' but it would not match 'rollercoaster', however if you took off the trailing \b then it would match the first part of 'rollercoaster'
|
2

Consider breaking this problem up into two pieces:

  1. filter out the items that match the given regular expression
  2. determine if that filtered list has 0 matches in it
const sampleStringData = ["frog", "pig", "tiger"];

const matches = sampleStringData.filter((animal) => /any.regex.here/.test(animal));

if (matches.length === 0) {
  console.log("No matches");
}

Comments

2

Andersh's solution will not work if you have global flags.
A true return will toggle on and off on future identical tests.

regexArray.some( rx => rx.test( "a" ))    // true
regexArray.some( rx => rx.test( "a" ))    // false
regexArray.some( rx => rx.test( "a" ))    // true

(read why here)

This works and is also a one-liner:

const isMatch = regexList.map( rx => rx.source).includes( string )

.source returns the text string of the RegExp pattern.
.map returns an array of these strings.
.includes returns if the string is in the array
(if you need the index, use .indexOf)

Alternatively:

function isInsideArray( string, regexArray ){
  return regexArray.map( regex => regex.source).includes( string )
}

function isInsideArray_Andersh( string, regexArray ){
  return regexArray.some( rx => rx.test( string )) 
}

    
const list_rx = [ /apple/g, /pear/g, /banana/g ],
      string  = "pear"

console.log( isInsideArray( string, list_rx ))
console.log( 'Andersh:', isInsideArray_Andersh( string, list_rx ))
console.log( 'Andersh (same test):', isInsideArray_Andersh( string, list_rx ))

Comments

1

look this way...

function matchInArray(stringSearch, arrayExpressions){
    var position = String(arrayExpressions).search(stringSearch);
    var result = (position > -1) ? true : false
    return result;
}

1 Comment

Although this code may answer the question, providing additional context regarding why and/or how it answers the question would significantly improve its long-term value. Please edit your answer to add some explanation.
1

You can join all regular expressions into single one. This way the string is scanned only once. Even with a sligthly more complex regular expression.

var thisExpressions = [ /something/, /something_else/, /and_something_else/];
var thisString = 'else';


function matchInArray(str, expr) {
    var fullExpr = new RegExp(expr
        .map(x=>x.source) // Just if you need to provide RegExp instances instead of strings or ...
        // .map(x=>x.substring(1, x.length -2)  // ...if you need to provide strings enclosed by "/" like in original question.
        .join("|")
    )
    return str.match(fullExpr);

};


if (matchInArray(thisString, thisExpressions)) {
    console.log ("Match!!");
} 

In fact, even with this approach, if you need check the same expression set against multiple strings, this is a few suboptimal because you are building (and compiling) the same regular expression each time the function is called.

Better approach would be to use a function builder like this:

var thisExpressions = [ /something/, /something_else/, /and_something_else/];
var thisString = 'else';

function matchInArray_builder(expr) {
    var fullExpr = new RegExp(expr
        .map(x=>x.source) // Just if you need to provide RegExp instances instead of strings or ...
        // .map(x=>x.substring(1, x.length -2)  // ...if you need to provide strings enclosed by "/" like in original question.
        .join("|")
    )   

    return function (str) {
        return str.match(fullExpr);

    };
};  

var matchInArray = matchInArray_builder(thisExpressions);

if (matchInArray(thisString)) {
    console.log ("Match!!");
} 

6 Comments

What about let's say I wanted the index of the value that was matched?
matchInArray(thisString, thisExpressions).index
Would it be going after the var matchInArray = matchInArray_builder(thisExpressions);? like this: var matchInArray = matchInArray_builder(thisExpressions); var index = matchInArray(thisString, thisExpressions).index?
No. I put an extra parameter by mistake. matchInArray() function returns the outcome of String.match(). Hence, in fact the "if" condition isn't a boolean value but a complete structure (which evaluates to true) reporting the matched substring and its position…
ahhhhh... i misread your return statement within the function :)
|
0
let expressions = [ '/something/', '/something_else/', '/and_something_else/'];

let str = 'else';

here will be the check for following expressions:

if( expressions.find(expression => expression.includes(str) ) ) {

}

using Array .find() method to traverse array and .include to check substring

Comments

0

If you would like to use String.match(), in case your array contains both match strings and regular expressions, you can do

let str = "The quick brown fox";
let matches = ["fox", "The.*fox", /the.*fox/i];
let strInMatches = matches.some(match => str.match(match));
console.log(strInMatches);

Comments

0

This returns the first match, or undefined if no regex matches.

function matchAny(str, regExps) {
  for (const regex of regExps) {
    const match = str.match(regex)
    if (match) {
      return match
    }
  }
}

This returns true if at least 1 regex matches, or false if no regex matches.

function matchSome(str, regExps) {
  for (const regex of regExps) {
    const exists = regex.test(str)
    if (exists) {
      return exists
    }
  }
  return false
}

Comments

-2

So we make a function that takes in a literal string, and the array we want to look through. it returns a new array with the matches found. We create a new regexp object inside this function and then execute a String.search on each element element in the array. If found, it pushes the string into a new array and returns.

// literal_string: a regex search, like /thisword/ig
// target_arr: the array you want to search /thisword/ig for.

function arr_grep(literal_string, target_arr) {
  var match_bin = [];
  // o_regex: a new regex object.
  var o_regex = new RegExp(literal_string);
  for (var i = 0; i < target_arr.length; i++) {
    //loop through array. regex search each element.
    var test = String(target_arr[i]).search(o_regex);
    if (test > -1) {
    // if found push the element@index into our matchbin.
    match_bin.push(target_arr[i]);
    }
  }
  return match_bin;
}

// arr_grep(/.*this_word.*/ig, someArray)

1 Comment

this solution is too complicated considering the simplicity of the problem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.