TypeError: matchAll/replaceAll 必须与全局正则表达式一起使用
当 String.prototype.matchAll()
或 String.prototype.replaceAll()
方法与没有设置 global
标志的 RegExp
对象一起使用时,会发生 JavaScript 异常 "TypeError: matchAll/replaceAll 必须使用全局 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)
错误类型
出了什么问题?
String.prototype.matchAll()
和 String.prototype.replaceAll()
方法需要一个设置了 global
标志的 RegExp
对象。此标志表示正则表达式可以匹配输入字符串的所有位置,而不是在第一个匹配项处停止。虽然在使用这些方法时 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" ]]