4

I have a string containing a regular expression in literal notation, e.g.:

var pattern = '/abc/i';

How can I create a regular expression object from that string?

Of course, I could just use eval:

eval(pattern); // /abc/i

But I'd like to avoid that.

12
  • Are you sure the string will always be a regex? Commented Apr 4, 2017 at 10:41
  • 1
    Uh, new RegExp(pattern) ? -> developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Apr 4, 2017 at 10:41
  • @WiktorStribiżew it's supposed to be a regex, but it could contain a typo. Commented Apr 4, 2017 at 10:43
  • 1
    @adeneo that gives me /\/abc\/i/ Commented Apr 4, 2017 at 10:43
  • So write valid patterns Commented Apr 4, 2017 at 10:44

3 Answers 3

2

You can probably do something like this:

var pattern = '/ab*c/gi';

if ((m = /^\/(.*)\/([gim]*)$/i.exec(pattern)) != null) {
   restr = m[1], flag = m[2], re = new RegExp(restr, flag)
}
//=> /ab*c/gi

You may need to add handling of special regex meta characters if you want them to be treated literally.

Sign up to request clarification or add additional context in comments.

1 Comment

Escaping is not needed, the characters should be treated just like a regex literal. However, wouldn't it be easier to use capturing groups in order to match both parts at once, e.g. /^\/(.*)\/([gim]*)$/.exec(pattern)?
2

You can use a combo of substr and lastIndexOf like this:

var pattern = '/abc/i';

// the index of the first "/" is always 1
var index = pattern.lastIndexOf('/');          // index of the last "/"

var thePattern = pattern.substr(1, index - 1); // the actual pattern part
var theFlags   = pattern.substr(index + 1);    // the flags part

var regex = new RegExp(thePattern, theFlags);

console.log(regex);

Comments

2

I just created a function for that. Check it.

  • Substring from 1 ( to avoid first /) to last index of /). -> we got the pattenr.
  • substring from last index of / +1 to string length -> got the flags

Then pass the 2 arguments to the new RegExp function

function formRegEx(str){
  var reg=str.substring(1,str.lastIndexOf('/'));
  var flags=str.substring(str.lastIndexOf('/')+1,str.length);
  return new RegExp(reg,flags);
  
}
console.log(formRegEx('/abc/i'));
console.log(formRegEx('/[a-zA-Z]/ig'));

Update

From OP's comment on question, abc/i may present which should be treated as invalid.

So, a test can be done to check the validity

/^\/.*\/[igm]*$/

and then check for no existence of // by testing against

/[^\\]\/[^igm]/

The above function can be rewritten as

function formRegEx(str){
  if(!/^\/.*\/[igm]*$/.test(str)) return "Invalid RE";
  if(/[^\\]\/[^igm]/.test(str)) return "Invalid RE";
  var reg=str.substring(1,str.lastIndexOf('/'));
  var flags=str.substring(str.lastIndexOf('/')+1,str.length);
  return new RegExp(reg,flags);
  
}
console.log(formRegEx('/abc/ig')); // true
console.log(formRegEx('/abc//i'));  // false
console.log(formRegEx('/a/bc/i')); //false
console.log(formRegEx('/[a-zA-Z]/ig')); // true
console.log(formRegEx('abc/ig'));  // invalid
console.log(formRegEx('abci')); // invalid
console.log(formRegEx('/abc/ik')); // invalid

Comments

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.