preg_replace($pattern, $replacement, $subject) tìm mọi phần khớp với một biểu thức chính quy trong chuỗi và thay thế chúng. preg_replace('/\s+/', ' ', $text) biến mỗi dãy khoảng trắng, tab và dấu xuống dòng thành một khoảng trắng duy nhất.
Chuỗi gốc không bị thay đổi; preg_replace() trả về một chuỗi mới. \b đánh dấu ranh giới từ, đó là lý do cats được giữ nguyên.
Tham chiếu ngược: {1} và \1
Trong chuỗi thay thế, $1 đại diện cho phần mà nhóm bắt thứ nhất đã khớp, $2 cho nhóm thứ hai, và $0 cho toàn bộ phần khớp. Dùng chúng để sắp xếp lại đoạn văn bản đã khớp.
Hãy viết chuỗi thay thế trong dấu nháy đơn. Trong dấu nháy kép, "\1" trở thành một escape bát phân (byte 0x01) còn "${1}" bị đọc thành biến tên 1, vốn chưa được định nghĩa và dùng cú pháp chuỗi đã bị đánh dấu deprecated từ PHP 8.2. '\1' trong dấu nháy đơn hoạt động giống '$1', nhưng $1 là cách viết phổ biến hơn.
Xóa ký tự không phải chữ và số
Một lớp ký tự phủ định, [^...], khớp với mọi thứ không có trong danh sách. Thay nó bằng '' là xóa nó đi. Với văn bản ngôn ngữ khác, hãy dùng các lớp Unicode \p{L} (mọi chữ cái) và \p{N} (mọi chữ số) cùng modifier u, nếu không bạn sẽ xóa mất é, ü, chữ có dấu tiếng Việt và mọi ký tự tiếng Nhật.
Tạo slug cho URL
Vài mẫu nối tiếp nhau biến một tiêu đề thành slug cho URL. Đầu tiên chuyển thành chữ thường, thay mỗi dãy ký tự không phải chữ và số bằng một dấu gạch nối, rồi cắt dấu gạch nối ở hai đầu:
Nhiều mẫu, giới hạn và số lần thay
$pattern và $replacement có thể là mảng: mỗi mẫu được thay bằng chuỗi thay thế ở cùng chỉ số, theo thứ tự. Đối số thứ tư giới hạn số lần thay cho mỗi mẫu (-1 nghĩa là không giới hạn), còn đối số thứ năm nhận số lần thay thế đã thực hiện.
Tính chuỗi thay thế với preg_replace_callback
Khi chuỗi thay thế phụ thuộc vào phần khớp, hãy dùng preg_replace_callback(). Hàm này gọi hàm của bạn một lần cho mỗi phần khớp với mảng $matches và chèn vào bất cứ thứ gì hàm trả về. Một arrow function giúp các callback ngắn nằm gọn trên một dòng.
preg_replace_callback_array() nhận một mảng các cặp pattern => callback khi nhiều mẫu, mỗi mẫu cần một hàm riêng.
Chuỗi thay thế lấy từ biến
Một dấu $ hoặc dấu gạch chéo ngược trong chuỗi thay thế đều mang ý nghĩa, nên một chuỗi thay thế đến từ người dùng hay cơ sở dữ liệu có thể bị biến dạng. Giá $10 bị đọc thành tham chiếu đến nhóm 10, vốn không tồn tại, nên kết quả là rỗng:
Khi cả đoạn cần tìm lẫn chuỗi thay thế đều không phải mẫu, str_replace() là lựa chọn đơn giản và nhanh hơn. Để thử một mẫu trước khi thay bất cứ thứ gì, xem preg_match().
Câu hỏi thường gặp
Làm sao dùng tham chiếu ngược trong preg_replace?
Gọi các nhóm bắt là $1, $2 (hoặc \1) trong chuỗi thay thế: preg_replace('/(\d{4})-(\d{2})-(\d{2})/', '$3/$2/$1', '2026-03-14') trả về "14/03/2026". Viết chuỗi thay thế trong dấu nháy đơn, và dùng ${1} khi ngay sau tham chiếu là một chữ số.
Làm sao xóa mọi ký tự không phải chữ và số trong PHP?
preg_replace('/[^a-zA-Z0-9]/', '', $s) chỉ giữ lại chữ cái và chữ số ASCII. Để giữ chữ cái của mọi ngôn ngữ (é, ü, 日本語, chữ có dấu tiếng Việt), dùng các lớp Unicode với modifier u: preg_replace('/[^\p{L}\p{N}]/u', '', $s).
preg_replace và preg_replace_callback khác nhau thế nào?
preg_replace() nhận một chuỗi thay thế cố định với các chỗ giữ $1. preg_replace_callback() gọi một hàm cho mỗi phần khớp và dùng giá trị trả về của hàm, nên bạn có thể tính ra chuỗi thay thế: viết hoa nó, tính toán với nó, hoặc tra nó trong một mảng.
Nên dùng str_replace hay preg_replace?
Dùng str_replace() khi bạn thay một đoạn văn bản cố định: nó nhanh hơn và không cần escape. Dùng preg_replace() khi đoạn cần thay theo một mẫu, chẳng hạn một dãy khoảng trắng bất kỳ, một chữ số bất kỳ hoặc ranh giới từ.
Làm sao chỉ thay phần khớp đầu tiên với preg_replace?
Truyền giới hạn ở đối số thứ tư: preg_replace('/\d+/', '#', 'a1 b2 c3', 1) trả về "a# b2 c3". Đối số thứ năm, truyền theo tham chiếu, nhận số lần thay thế đã thực hiện.