TypeError: matchAll/replaceAll must be called with a global RegExp
Ngoại lệ JavaScript "TypeError: matchAll/replaceAll must be called with a global RegExp" xảy ra khi phương thức String.prototype.matchAll() hoặc String.prototype.replaceAll() được sử dụng với một đối tượng RegExp không có cờ global được đặt.
Thông báo
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)
Loại lỗi
TypeError
Điều gì đã xảy ra?
Các phương thức String.prototype.matchAll() và String.prototype.replaceAll() yêu cầu một đối tượng RegExp với cờ global được đặt. Cờ này chỉ ra rằng biểu thức chính quy có thể khớp với tất cả các vị trí của chuỗi đầu vào, thay vì dừng lại ở kết quả khớp đầu tiên. Mặc dù cờ g là thừa khi sử dụng các phương thức này (vì các phương thức này luôn thực hiện thay thế toàn cục), chúng vẫn được yêu cầu để làm rõ ý định.
Điều đáng chú ý là việc kiểm tra cờ g được thực hiện trong các phương thức matchAll và replaceAll. Nếu bạn sử dụng phương thức [Symbol.matchAll]() của RegExp thay thế, bạn sẽ không gặp lỗi này, nhưng sẽ chỉ có một kết quả khớp duy nhất.
Ví dụ
>Các trường hợp không hợp lệ
"abc".matchAll(/./); // TypeError
"abc".replaceAll(/./, "f"); // TypeError
Các trường hợp hợp lệ
Nếu bạn muốn thực hiện khớp/thay thế toàn cục: hãy thêm cờ g, hoặc tạo một đối tượng RegExp mới với cờ g, nếu bạn muốn giữ nguyên regex gốc.
[..."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"
Nếu bạn chỉ muốn thực hiện một lần khớp/thay thế: hãy sử dụng String.prototype.match() hoặc String.prototype.replace() thay thế. Bạn cũng có thể sử dụng phương thức [Symbol.matchAll]() nếu bạn muốn một iterator như matchAll trả về chỉ chứa một kết quả khớp, nhưng làm vậy sẽ rất khó hiểu.
"abc".match(/./); // [ "a" ]
"abc".replace(/./, "f"); // "fbc"
[..././[Symbol.matchAll]("abc")]; // [[ "a" ]]