rustyshackleford
rustyshackleford

Reputation: 731

Turning a regex returned as a string from an API into a valid RegEx object in JavaScript

I'm fetching a regular expression from an external API, and it comes back as a string. I want to use the regex for address validation, but I can't seem to properly escape the unwanted characters after calling new RegExp() on the string.

Here's the regex I want to use:

console.log(regexFromAPI);

Output

/((\W|^)box\s+(#\s*)?\d+|post\s+office|(\W|^)p\.?\s*o\.?\s+(#\s*)?\d+)/i

However, I can't use that -- I need it to actually be a regex first.

If I do, for example:

const pattern = new RegExp(regexFromAPI);

and then:

console.log(pattern);

I get the following:

Output

//((W|^)boxs+(#s*)?d+|posts+office|(W|^)p.?s*o.?s+(#s*)?d+)/i/

My question is... why is this happening, and how can I avoid it? I want to use my string literal as a regex.

Thanks in advance.

Upvotes: 1

Views: 404

Answers (2)

Jack Bashford
Jack Bashford

Reputation: 44145

Take off the slashes and flags, then reconstruct it:

const str = String.raw`/((\W|^)box\s+(#\s*)?\d+|post\s+office|(\W|^)p\.?\s*o\.?\s+(#\s*)?\d+)/i`;
let regexBody = str.slice(1, str.lastIndexOf("/"));
let flags = str.split("/")[str.split("/").length - 1];
let regex = new RegExp(regexBody, flags);
console.log(regex);

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 371203

The RegExp constructor does not expect a string with / delimiters, nor with options past the final /. If you do that, the pattern generated from calling new RegExp with it will result in one that matches a string which starts with a literal forward slash /, and ends with a forward slash / followed by the flag characters (here, i).

Instead, you should pass the pattern string without / delimiters, and pass the flags as the second argument - you can extract these easily by using another regular expression:

const fullPatternStr = String.raw`/((\W|^)box\s+(#\s*)?\d+|post\s+office|(\W|^)p\.?\s*o\.?\s+(#\s*)?\d+)/i`;

const [, pattern, flags] = fullPatternStr.match(/\/(.*)\/([a-z]*)/);
const regex = new RegExp(pattern, flags);
console.log(regex);

Upvotes: 3

Related Questions