new RegExp()

Builds a regular expression object from a pattern string or another regex, with optional flags.

Signature
new RegExp(pattern)
new RegExp(pattern, flags)
RegExp(pattern)
RegExp(pattern, flags)
  • Added in JavaScript ES3 (1999)

Parameters

ParameterTypeDescription
$patternstring | RegExpThe text of the regular expression. May also be an existing RegExp object, whose source is then reused.
$flagsoptionalstringAny combination of d, g, i, m, s, u, v and y. If pattern is a RegExp, this string replaces that object's flags entirely and resets lastIndex to 0.

Return value

RegExpA new RegExp object. Called without new, with a regex whose constructor is RegExp and no flags argument, the pattern is returned unchanged instead of copied.

Errors

SyntaxError if the pattern cannot be parsed, or if flags contains a repeated or unrecognised character.

Changelog

  • PHP ES2015new RegExp(regex, flags) became legal; previously supplying flags alongside a regex pattern threw a TypeError.
  • PHP ES2018The s (dotAll) flag joined the accepted set; d arrived in ES2022 and v in ES2024.

A regex literal such as /\d+/g is compiled once when the script is parsed, so it is the right choice whenever the pattern is known in advance. Reach for the constructor only when the pattern is assembled at runtime — from a user's search box, a config file, or by concatenating the source of smaller regexes.

The backslash tax

The first argument is an ordinary string literal, so the string parser consumes one level of escaping before the regex parser ever sees the text. "\d" is just the letter d; you need "\\d". Template literals behave the same way. This is the single most common reason a constructed regex silently matches the wrong thing.

Copying a regex

Passing an existing regex as pattern reuses its source. If you also pass flags, that string replaces the original flags rather than merging with them, and lastIndex is reset to 0. That makes it the standard way to hand back a g-flagged clone without mutating the caller's object.

Untrusted input

Interpolating user text straight into a pattern lets them inject regex syntax. Escape it, or use String.prototype.includes() when you only need a substring test.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Turn a user's search term into a case-insensitive highlighter
  • Build a validation pattern from a list of allowed values loaded at startup
  • Clone a regex with the g flag added so a helper can iterate without mutating the caller's object

Frequently asked questions

Why does my regex built with new RegExp not match anything?

Almost always because backslashes were not doubled in the string. "\d" becomes the plain letter d before the regex engine sees it, so write "\\d" (or use a regex literal). Log the .source property to see the pattern the engine actually compiled.

Is new RegExp slower than a regex literal?

Yes, because the pattern is compiled every time the constructor runs, whereas a literal is compiled once at parse time. Hoist the construction out of loops; if the pattern never changes, use a literal.

How do I add the g flag to an existing regex?

Build a new one: new RegExp(re.source, re.flags + "g"). Flags are read-only accessors, so you cannot set them in place, and the second argument replaces rather than merges — you must include the original flags yourself.

More examples

Copying a regex and replacing its flags

The clone gets exactly the flags you pass. Passing an empty string strips every flag the original had, which is why merging requires reading base.flags yourself.

Example · javascript
const base = /gray|grey/;
const all = new RegExp(base, "gi");

console.log(all.flags);            // "gi"
console.log(JSON.stringify(base.flags)); // "" - original untouched
console.log("Gray grey GREY".match(all));

// flags REPLACE, they do not merge:
console.log(JSON.stringify(new RegExp(all, "").flags));

What the constructor rejects

Bad syntax and duplicate flags both throw SyntaxError at construction time. Note the last two lines: without new, a plain regex argument is passed straight through, so you do not get an independent lastIndex.

Example · javascript
try { new RegExp("a(b"); }
catch (e) { console.log(e.name, "-", e.message); }

try { new RegExp("a", "gg"); }
catch (e) { console.log(e.name, "-", e.message); }

console.log(JSON.stringify(new RegExp("").source)); // "(?:)"

const r = /x/;
console.log(RegExp(r) === r);     // true  - no copy
console.log(new RegExp(r) === r); // false - fresh object

Discussion

  • Be the first to comment on this lesson.