Người dùng nhập $& làm nội dung thay thế nhưng kết quả vẫn giữ nguyên từ cũ. Trong JavaScript, tham số chuỗi thay thế của replace và replaceAll có cú pháp riêng. Tìm kiếm bằng chuỗi thường không có nghĩa mọi ký tự ở phía thay thế cũng được chèn nguyên văn.
1. Chuỗi thay thế có ký hiệu đặc biệt
console.log('A X B'.replace('X', '$&')); // A X B
console.log('A X B'.replace('X', '$$')); // A $ B
console.log('X X'.replaceAll('X', '[$&]')); // [X] [X]
$& đại diện cho phần vừa khớp, còn $$ tạo một dấu $. Những quy tắc này vẫn áp dụng khi mẫu tìm kiếm là chuỗi 'X'. Vì vậy, đưa trực tiếp văn bản tùy ý vào tham số replacement có thể cho kết quả khác nội dung gốc.
2. Trả nội dung từ callback để giữ nguyên văn
const replacement = '$&';
console.log('A X B'.replace('X', () => replacement)); // A $& B
console.log('X X'.replaceAll('X', () => replacement)); // $& $&
Chuỗi trả về từ callback không được diễn giải lại theo cú pháp replacement. Đây là lựa chọn rõ ràng khi thao tác phải chèn đúng nội dung đã nhận. Nếu cố ý dùng nhóm bắt như $1 để định dạng lại kết quả regex, giữ cơ chế replacement string và kiểm thử theo mục tiêu đó.
3. Mẫu tìm kiếm và nội dung thay thế là hai quyết định riêng
console.log('a.b.c'.replaceAll('.', '-')); // a-b-c
console.log('a.b.c'.replaceAll(/./g, '-')); // -----
console.log('X X'.replace('X', 'Y')); // Y X
console.log('X X'.replaceAll('X', 'Y')); // Y Y
Dấu chấm trong chuỗi tìm kiếm được hiểu đúng là dấu chấm; trong regex /./g nó khớp từng ký tự của ví dụ. Nếu yêu cầu tìm đúng một chuỗi được nhập, có thể truyền chuỗi trực tiếp vào replaceAll thay vì tự dựng regex.
replace với mẫu chuỗi chỉ thay lần xuất hiện đầu tiên. replaceAll thay mọi lần khớp; khi truyền regex, regex phải có cờ g. Chọn phạm vi thay thế trước khi viết helper để tránh đổi nhiều vị trí ngoài dự kiến.
4. Viết helper với hợp đồng hẹp
Helper minh họa nhận ba chuỗi, tìm chính xác mọi lần xuất hiện không chồng lấn và chèn replacement nguyên văn. Nó từ chối mẫu tìm rỗng để tránh tạo nội dung ở các ranh giới ký tự ngoài ý định của tính năng.
function replaceLiteralAll(text, search, replacement) {
if ([text, search, replacement].some(value => typeof value !== 'string')) {
throw new TypeError('String arguments required');
}
if (search.length === 0) throw new RangeError('Empty search');
return text.replaceAll(search, () => replacement);
}
console.log(replaceLiteralAll('a.b.a', '.', '$&')); // a$&b$&a
console.log(replaceLiteralAll('X X', 'X', '')); // một dấu cách / one space
console.log(replaceLiteralAll('aaaa', 'aa', 'b')); // bb
Chuỗi kết quả được tạo mới; chuỗi đầu vào không bị sửa. Nội dung vừa chèn không tiếp tục được tìm và thay trong cùng lời gọi này. Nếu tính năng xử lý tài liệu lớn, đặt giới hạn kích thước đầu vào và đầu ra theo nhu cầu ứng dụng; bài không đưa ra ngưỡng hiệu năng chung.
5. Kiểm tra đúng cả hai phía của phép thay thế
- Mẫu tìm có dấu chấm, ngoặc hoặc dấu cộng.
- Nội dung thay thế chứa $&, $$ hoặc $1.
- Không khớp, khớp một lần và nhiều lần.
- Xóa bằng chuỗi thay thế rỗng.
- Mẫu rỗng bị từ chối theo hợp đồng của helper.
- Các lần khớp chồng lấn không được suy diễn thành thay thế đệ quy.
Tám khối ví dụ Việt–Anh đã chạy bằng Node.js, kèm kiểm tra dấu $, mẫu đặc biệt và đầu vào sai kiểu. Chưa kiểm thử trình biên tập trong trình duyệt hoặc đo hiệu năng. Tham khảo MDN String.replace và MDN String.replaceAll.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.