Tất cả bài viết

Biểu thức chính quy: cú pháp cơ bản và các mẫu thường gặp

Biểu thức chính quy (regex) là cách ngắn gọn để mô tả một khuôn mẫu văn bản — không phải một chuỗi cụ thể, mà là quy tắc mà chuỗi phải thỏa mãn. Thay vì duyệt từng ký tự trong vòng lặp, một biểu thức duy nhất có thể tìm hoặc kiểm tra một cấu trúc phức tạp.

Các khối cơ bản

  • Lớp ký tự\d (chữ số), \w (chữ cái/số/gạch dưới), \s (khoảng trắng), hoặc lớp tự định nghĩa như [a-zA-Z].
  • Bộ định lượng* (0 lần trở lên), + (1 lần trở lên), ? (0 hoặc 1 lần), {2,5} (từ 2 đến 5 lần).
  • Nhóm bắt (capture group) — dấu ngoặc đơn (...) đánh dấu một phần của kết quả khớp để dùng riêng sau đó, ví dụ khi thay thế.
  • Điểm neo (anchor)^$ gắn khuôn mẫu vào đầu hoặc cuối dòng.

Vì sao \w gần như "mù" với tiếng Việt

Trong bộ máy regex của JavaScript mà công cụ này sử dụng, \w luôn chỉ có nghĩa là [A-Za-z0-9_] — chữ cái ASCII, chữ số và dấu gạch dưới. Tiếng Việt có hệ thống dấu thanh và chữ cái mở rộng (ă, â, ê, ô, ơ, ư cùng các dấu sắc, huyền, hỏi, ngã, nặng), nên gần như mọi từ có dấu đều rơi ra ngoài phạm vi này: /^\w+$/.test('Việt Nam') trả về false ngay từ chữ "Việt". Thêm cờ u cũng không mở rộng định nghĩa của \w — để khớp đúng chữ tiếng Việt có dấu, cần dùng lớp thuộc tính Unicode như /^[\p{L}\p{M}]+$/u, trong đó \p{M} bắt các dấu kết hợp (combining marks) đứng tách rời khỏi chữ cái gốc.

Khớp tham lam và khớp lười

Mặc định, bộ định lượng "tham lam" — cố gắng khớp càng nhiều ký tự càng tốt, chỉ nhường lại khi điều đó cản trở việc tìm ra kết quả khớp. Ví dụ <.+> trên chuỗi <a>text</a> sẽ khớp từ dấu < đầu tiên đến dấu > cuối cùng. Thêm ? sau bộ định lượng (<.+?>) khiến nó trở nên "lười" — khớp càng ít càng tốt và dừng lại ở kết quả khớp hợp lệ đầu tiên.

Dùng để làm gì

  • Kiểm tra định dạng dữ liệu đầu vào (email, số điện thoại, mã bưu chính).
  • Tìm kiếm và thay thế hàng loạt theo khuôn mẫu thay vì khớp chính xác.
  • Trích xuất dữ liệu có cấu trúc từ log hoặc văn bản phi cấu trúc.

Backtracking thảm khốc

Các bộ định lượng lồng nhau như (a+)+ có thể buộc bộ máy regex thử một số lượng tổ hợp tăng theo cấp số mũ trên một số chuỗi đầu vào nhất định trước khi kết luận không có kết quả khớp — trang web hoặc máy chủ "đứng hình" với một biểu thức trông có vẻ đơn giản. Đây là một lớp lỗ hổng bảo mật thực sự (ReDoS), nên các bộ định lượng lồng nhau phức tạp cần được kiểm thử với những chuỗi dài "gần khớp", chứ không chỉ với các ví dụ mong đợi.

Dùng thử công cụ