Lập trình · 21/10/2026

JavaScript replace và replaceAll: giữ nguyên dấu $ trong chuỗi thay thế

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.

JavaScript replace và replaceAll: giữ nguyên dấu $ trong chuỗi thay thế

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.

Thảo luận

Bình luận 0

Đăng nhập để bình luận

Bạn cần có tài khoản để tham gia thảo luận và trả lời độc giả khác.

Đăng nhậpĐăng ký

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