Regex Quantifier
Ký tự meta như *, +, ?, {n,m} chỉ định số lần lặp lại. Chúng kiểm soát số lần phần tử trước đó xuất hiện.
Bộ lượng hóa regex là ký tự meta chỉ định số lần phần tử trước đó (ký tự, nhóm hoặc lớp ký tự) nên xuất hiện. Các bộ lượng hóa cơ bản là: * (không hoặc nhiều lần), + (một hoặc nhiều lần), ? (không hoặc một lần), {n} (chính xác n lần), {n,} (n lần trở lên), {n,m} (từ n đến m lần). Ví dụ, \d{3}-\d{4} khớp chính xác 3 chữ số, dấu gạch ngang, rồi 4 chữ số.
Theo mặc định, bộ lượng hóa là tham lam - chúng khớp càng nhiều ký tự càng tốt. Thêm ? sau bộ lượng hóa làm cho nó lười biếng (khớp càng ít càng tốt). Ví dụ, với đầu vào "<b>bold</b> and <b>more</b>", mẫu tham lam <b>.*</b> khớp toàn bộ chuỗi, trong khi mẫu lười biếng <b>.*?</b> khớp từng thẻ riêng biệt. Bạn có thể tham khảo sách regex chi tiết về hành vi bộ lượng hóa.
Bộ lượng hóa sở hữu (thêm + sau bộ lượng hóa, ví dụ *+, ++) khớp càng nhiều càng tốt và không bao giờ quay lui. Điều này có thể cải thiện hiệu suất đáng kể bằng cách ngăn chặn quay lui không cần thiết. Tuy nhiên, không phải tất cả engine regex đều hỗ trợ bộ lượng hóa sở hữu - JavaScript không hỗ trợ, nhưng Java và PCRE thì có.
Thảm họa quay lui là vấn đề hiệu suất nghiêm trọng liên quan đến bộ lượng hóa. Mẫu như (a+)+b với đầu vào "aaaaaaaaaaac" gây ra quay lui theo cấp số mũ vì engine thử mọi cách phân chia ký tự "a" giữa các nhóm. Điều này có thể đóng băng ứng dụng hoặc gây ra lỗ hổng ReDoS (Regular Expression Denial of Service). Tránh bộ lượng hóa lồng nhau và sử dụng nhóm nguyên tử hoặc bộ lượng hóa sở hữu khi có thể.
Một quan niệm sai lầm phổ biến là .* khớp "mọi thứ". Theo mặc định, . không khớp ký tự xuống dòng, nên .* chỉ khớp trong một dòng. Cờ s (dotAll) thay đổi hành vi này. Ngoài ra, {0,} tương đương * và {1,} tương đương +, nhưng dạng ký hiệu dễ đọc hơn cho các trường hợp phổ biến. Bạn có thể tham khảo sách bảo mật lập trình về phòng chống ReDoS.
Từ góc độ đếm ký tự, bộ lượng hóa xác định bao nhiêu ký tự một mẫu tiêu thụ. Hiểu sự khác biệt giữa khớp tham lam và lười biếng là thiết yếu khi sử dụng regex để trích xuất và đếm các phần văn bản cụ thể. Ví dụ, trích xuất nội dung giữa dấu ngoặc kép đòi hỏi khớp lười biếng để tránh khớp quá nhiều.