类型错误:matchAll/replaceAll 必须使用全局 RegExp 调用

JavaScript 异常“TypeError:当 String.prototype.matchAll()String.prototype.replaceAll() 方法与未设置 global 标志的 RegExp 对象一起使用时,会发生“matchAll/replaceAll 必须使用全局 RegExp 调用”。

¥The JavaScript exception "TypeError: matchAll/replaceAll must be called with a global RegExp" occurs when the String.prototype.matchAll() or String.prototype.replaceAll() method is used with a RegExp object that does not have the global 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

TypeError

什么地方出了错?

¥What went wrong?

String.prototype.matchAll()String.prototype.replaceAll() 方法需要设置了 global 标志的 RegExp 对象。此标志表示正则表达式可以匹配输入字符串的所有位置,而不是在第一次匹配时停止。虽然使用这些方法时 g 标志是多余的(因为这些方法总是进行全局替换),但它们仍然是明确意图所必需的。

¥The String.prototype.matchAll() and String.prototype.replaceAll() methods require a RegExp object with the global 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 the g flag is redundant when using these methods (because these methods always do a global replacement), they are still required to make the intention clear.

值得注意的是,g 标志验证是在 matchAllreplaceAll 方法中完成的。如果你改用 RegExp[Symbol.matchAll]() 方法,则不会出现此错误,但只会有一个匹配项。

¥It's worth noting that the g flag validation is done in the matchAll and replaceAll methods. If you use the [Symbol.matchAll]() method of RegExp instead, you won't get this error, but there will only be a single match.

示例

¥Examples

无效案例

¥Invalid cases

js
"abc".matchAll(/./); // TypeError
"abc".replaceAll(/./, "f"); // TypeError

有效案例

¥Valid cases

如果你打算进行全局匹配/替换:如果要保持原始正则表达式不变,请添加 g 标志或使用 g 标志构造一个新的 RegExp 对象。

¥If you intend to do global matching/replacement: either add the g flag, or construct a new RegExp object with the g flag, if you want to keep the original regex unchanged.

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]() 方法,但这样做会非常令人困惑。

¥If you only intend to do a single matching/replacement: use String.prototype.match() or String.prototype.replace() instead. You can also use the [Symbol.matchAll]() method if you want an iterator like matchAll returns that only contains one match, but doing so will be very confusing.

js
"abc".match(/./); // [ "a" ]
"abc".replace(/./, "f"); // "fbc"

[..././[Symbol.matchAll]("abc")]; // [[ "a" ]]

也可以看看