TypeError: matchAll/replaceAll must be called with a global RegExp
The JavaScript exception "TypeError: matchAll/replaceAll must be called with a global RegExp" occurs when theString.prototype.matchAll()
orString.prototype.replaceAll()
method is used with aRegExp
object that does not have theglobal
flag set.
Message
TypeError: String.prototype.matchAll called with a non-global RegExp argument (V8-based)TypeError: String.prototype.replaceAll called with a non-global RegExp argument (V8-based)TypeError: matchAll must be called with a global RegExp (Firefox)TypeError: replaceAll must be called with a global RegExp (Firefox)TypeError: String.prototype.matchAll argument must not be a non-global regular expression (Safari)TypeError: String.prototype.replaceAll argument must not be a non-global regular expression (Safari)
Error type
What went wrong?
TheString.prototype.matchAll()
andString.prototype.replaceAll()
methods require aRegExp
object with theglobal
flag set. This flag indicates that the regular expression can match all locations of the input string, instead of stopping at the first match. Although theg
flag is redundant when using these methods (because these methods always do a global replacement), they are still required to make the intention clear.
It's worth noting that theg
flag validation is done in thematchAll
andreplaceAll
methods. If you use the[Symbol.matchAll]()
method ofRegExp
instead, you won't get this error, but there will only be a single match.
Examples
Invalid cases
"abc".matchAll(/./); // TypeError"abc".replaceAll(/./, "f"); // TypeError
Valid cases
If you intend to do global matching/replacement: either add theg
flag, or construct a newRegExp
object with theg
flag, if you want to keep the original regex unchanged.
[..."abc".matchAll(/./g)]; // [[ "a" ], [ "b" ], [ "c" ]]"abc".replaceAll(/./g, "f"); // "fff"const existingPattern = /./;const newPattern = new RegExp( existingPattern.source, `${existingPattern.flags}g`,);"abc".replaceAll(newPattern, "f"); // "fff"
If you only intend to do a single matching/replacement: useString.prototype.match()
orString.prototype.replace()
instead. You can also use the[Symbol.matchAll]()
method if you want an iterator likematchAll
returns that only contains one match, but doing so will be very confusing.
"abc".match(/./); // [ "a" ]"abc".replace(/./, "f"); // "fbc"[..././[Symbol.matchAll]("abc")]; // [[ "a" ]]