TypeError: matchAll/replaceAll must be called with a global RegExp
当使用 String.prototype.matchAll() 或 String.prototype.replaceAll() 方法时,如果使用的 RegExp 对象未设置 global 标志,则会抛出 JavaScript 异常 "TypeError: matchAll/replaceAll must be called with a global RegExp"。
消息
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)
错误类型
TypeError
哪里出错了?
String.prototype.matchAll() 和 String.prototype.replaceAll() 方法要求 RegExp 对象设置 global 标志。此标志表示正则表达式可以匹配输入字符串的所有位置,而不是在第一次匹配时停止。尽管在使用这些方法时 g 标志是多余的(因为这些方法总是执行全局替换),但仍需要它们来明确意图。
值得注意的是,g 标志验证是在 matchAll 和 replaceAll 方法中完成的。如果你改用 RegExp 的 [Symbol.matchAll]() 方法,则不会出现此错误,但只会有一个匹配项。
示例
无效案例
js
"abc".matchAll(/./); // TypeError
"abc".replaceAll(/./, "f"); // TypeError
有效情况
如果你打算进行全局匹配/替换:请添加 g 标志,或者如果想保持原始正则表达式不变,则使用 g 标志构造一个新的 RegExp 对象。
js
[..."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"
如果你只打算进行单个匹配/替换:请改用 String.prototype.match() 或 String.prototype.replace()。如果你想要一个类似 matchAll 返回的迭代器,且只包含一个匹配项,也可以使用 [Symbol.matchAll]() 方法,但这会非常令人困惑。
js
"abc".match(/./); // [ "a" ]
"abc".replace(/./, "f"); // "fbc"
[..././[Symbol.matchAll]("abc")]; // [[ "a" ]]