94

How do you check, in JavaScript, if a string is a proper regular expression that will compile?

For example, when you execute the following javascript, it produces an error.

var regex = new RegExp('abc ([a-z]+) ([a-z]+))');
// produces:
// Uncaught SyntaxError: Invalid regular expression: /abc ([a-z]+) ([a-z]+))/: Unmatched ')'

How does one determine if a string will be a valid regex or not?

13
  • 11
    You need a regex to test a regex? lol Commented Jun 22, 2013 at 12:41
  • 1
    I want to check that the input string is a valid regular exp or no Commented Jun 22, 2013 at 12:49
  • 42
    Why is this 'not a real question' or 'closed' ? Or negative feedback? I found my answer here, with the exact problem as described ! Commented Sep 26, 2014 at 14:38
  • 3
    Exactly.. unless it was edited, there's nothing vague about this question - valid expressions are those that will compile. Since we're talking about javascript here, it only makes sense to assume that this means ES expressions. Commented Nov 10, 2015 at 14:48
  • 1
    @FlorianMertens the question has been edited (quite a lot), you can vote for it to be re-opened as the question is now much better. Commented Dec 7, 2018 at 16:10

6 Answers 6

129

You can use try/catch and the RegExp constructor:

var isValid = true;
try {
    new RegExp("the_regex_to_test_goes_here");
} catch(e) {
    isValid = false;
}

if(!isValid) alert("Invalid regular expression");
Sign up to request clarification or add additional context in comments.

14 Comments

@Jak: If you provide more information about what exactly "does not work" then we might be able to help you. But only saying "it does not work" gives us nothing. What input do you try? What output do you get? Are you getting a different error?
I replace my text box value instead of the_regex_to_test_goes_here but it doesn't determine that the text box value is valid or no. is my question's information enough now?
@JakSamun: Post a jsfiddle.com link with what you did, and tell us how the result was different than what you expected.
@DmitryDavydov that regex is indeed "correct" technically, although it's very confusing. Note that the behavior you cite is POSIX standard (The special characters ... shall lose their special meaning within a bracket expression).
Doesn't work in Chrome 63 - seems to accept any value in the constructor without throwing.
|
4

Here is a little function that checks the validity of both types of regexes, strings or patterns:

function validateRegex(pattern) {
    var parts = pattern.split('/'),
        regex = pattern,
        options = "";
    if (parts.length > 1) {
        regex = parts[1];
        options = parts[2];
    }
    try {
        new RegExp(regex, options);
        return true;
    }
    catch(e) {
        return false;
    }
}

The user will be able to test both test and /test/g for example. Here is a working fiddle.

3 Comments

This functions allows any arbitrary strings in so I am not sure this does what op wants
(did you downvote? lol) My answer and the other answer basically do the exact same thing, with the exception that I also take into account possible options inside the pattern. And, to be honest, what OP wanted was just to "check if the input string is a valid regex or not"; there were no constraints on the input length specifically, so any string could be passed as input. Moreover, I'm doing exactly what he asked, even returning proper true or false value.
You don't account for a regex with a / as part of it.
2

None of the answers here satisfied my need for checking that a string is a valid regex for other languages (Mostly php), because they either ignore the flags, the delimiters or escaped special characters, so I made my own function

function isValidRegex(s) {
  try {
    const m = s.match(/^([/~@;%#'])(.*?)\1([gimsuy]*)$/);
    return m ? !!new RegExp(m[2],m[3])
        : false;
  } catch (e) {
    return false
  }
}

console.log(isValidRegex('abc')) //False
console.log(isValidRegex('/abc/')) //True
console.log(isValidRegex('/ab#\/[c]/ig')) //True
console.log(isValidRegex('@ab#\/[c]@ig')) //Special delimiters: True
console.log(isValidRegex('/ab\/[c/ig')) //False
console.log(isValidRegex('/abc/gig')) //False

You can also derive this function to transform a string into a RegExp object

function stringToRegex(s) {
   const m = s.match(/^([/~@;%#'])(.*?)\1([gimsuy]*)$/);
   return m ? new RegExp(m[2], m[3]) : new RegExp(s);
}

console.log(stringToRegex('abc'))
console.log(stringToRegex('/abc/'))
console.log(stringToRegex('/ab#\/[c]/ig'))
console.log(stringToRegex('@ab#\/[c]@ig'))
try {
  console.log(stringToRegex('/ab#\/[c/ig'))
} catch (e) {
  console.log('Not a valid regex')
}

Comments

0

this function could handle the '/' char as a normal char in regex, and also consider escaping when is a common string. it will always return an Regex, null if not a good regex string.

function getRegex(regex) {
    try {
        regex = regex.trim();
        let parts = regex.split('/');
        if(regex[0] !== '/' || parts.length< 3){
          regex = regex.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); //escap common string
          return new RegExp(regex);
        }

        const option =parts[parts.length - 1];
        const lastIndex = regex.lastIndexOf('/');
        regex = regex.substring(1, lastIndex);
        return new RegExp(regex, option);
    } catch (e) {
        return null
    }
}

console.log(getRegex('ab/c'))
let htmlStartTag = getRegex('/<(?!/)(?!br)(.+?)(?<!/)>/mgs');
console.log(htmlStartTag)
let result = `</button><input id="warehouse-search-field-tablet"
class="form-control search-field"
 title="Warehouse Search Field" name="location" type="search" value="">content`.matchAll(htmlStartTag);
 console.log([...result])

Comments

-1
function isRegExp(regExp){
          try {
                new RegExp(regExp);
              } catch(e) {
                return false
              }
         return true
    }

ex:
isRegExp(/@(\w+)/g) = true

3 Comments

Can you add some explanation to the code you posted? "Brevity is acceptable, but fuller explanations are better." -How do I write a good answer?
i am just a beginner here, i'll improvise my answers with more understandable explanation for given code. For this, all experimented code is offline, let me push all code on github and hit here back with reference link. Thank You #HappyCoding
this is more or less a duplicate of the original answer from 2013..
-3

The question is solved, but if someone needs to define is the string either valid RegExp or not a RegExp at all.

You can use new Function() and templating inside of the function body with try ... catch and new RegExp() as mentioned earlier.

There is a snippet with the explanations:

const isRegExp = (string) => {
    try {
        return new Function(`
            "use strict";
            try {
                new RegExp(${string});
                return true;
            } catch (e) {
                return false;
            }
        `)();
    } catch(e) {
        return false;
    }
};

// Here the argument 'simplyString' shall be undefined inside of the function
// Function(...) catches the error and returns false
console.log('Is RegExp valid:', isRegExp('simplyString'));

// Here the argument shall cause a syntax error
// isRegExp function catches the error and returns false
console.log('Is RegExp valid:', isRegExp('string which is not a valid regexp'));

// Here the argument is not a valid RegExp, new RegExp(...) throws an error
// Function(...) catches the error and returns false
console.log('Is RegExp valid:', isRegExp('abc ([a-z]+) ([a-z]+))'));

// Valid RegExp, passed as a string
console.log('Is RegExp valid:', isRegExp('/^[^<>()[\]\\.,;:\s@\"]$/'));

// Valid RegExp, passed as a RegExp object
console.log('Is RegExp valid:', isRegExp(/^[^<>()[\]\\.,;:\s@\"]$/));

// Howewer, the code injection is possible here
console.log('Is RegExp valid:', isRegExp(');console.log("This is running inside of the Function(...) as well"'));

2 Comments

Two upvotes on an answer with a code injection vulnerability.
an article on DailyWTF sufficiently points out the problem with this answer: thedailywtf.com/articles/evaluating-regexes

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.