Regex cơ bản: mẹo viết biểu thức chính quy dễ hiểu, ít lỗi

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Regex (biểu thức chính quy) nổi tiếng là khó đọc, nhưng nếu nắm được vài khối xây dựng cơ bản và biết cách viết từng bước, nó trở thành công cụ rất mạnh để tìm kiếm, kiểm tra và thay thế văn bản. Bài này giới thiệu các ký hiệu quan trọng và vài mẹo để regex dễ đọc, dễ bảo trì.

Những khối cơ bản

Ký hiệuÝ nghĩaVí dụ
.Một ký tự bất kỳ (trừ xuống dòng)a.c khớp "abc", "a1c"
\dMột chữ số\d\d khớp "42"
\wChữ, số hoặc dấu gạch dưới\w+ khớp "user_1"
\sKhoảng trắng (space, tab, xuống dòng)a\sb khớp "a b"
[abc]Một ký tự trong tập[aeiou] khớp nguyên âm
[a-z]Một ký tự trong khoảng[0-9] tương đương \d
[^abc]Một ký tự không thuộc tập[^0-9] không phải chữ số
^ và $Đầu và cuối chuỗi^abc$ khớp đúng "abc"

Lượng từ: lặp bao nhiêu lần

  • *: 0 lần hoặc nhiều lần.
  • +: 1 lần hoặc nhiều lần.
  • ?: 0 hoặc 1 lần (tùy chọn).
  • {3}: đúng 3 lần; {2,5}: từ 2 đến 5 lần; {2,}: ít nhất 2 lần.

Mặc định lượng từ là "tham lam" (lấy nhiều nhất có thể). Thêm ? phía sau (như .*?) để chuyển sang "lười", lấy ít nhất có thể. Khác biệt này rất quan trọng khi tìm nội dung giữa hai dấu như thẻ HTML hay dấu nháy.

Nhóm, lựa chọn và nhóm bắt

  • (abc): nhóm và ghi nhớ kết quả (nhóm bắt) để lấy hoặc dùng lại.
  • (?:abc): nhóm nhưng không ghi nhớ.
  • a|b: hoặc a hoặc b, ví dụ (?:jpg|png|gif).
  • (?<ten>...): nhóm bắt có tên (được nhiều ngôn ngữ hỗ trợ), giúp đọc kết quả dễ hơn.

Ví dụ thực tế

Kiểm tra số điện thoại di động Việt Nam đơn giản

// JavaScriptconst phoneRegex = /^(0|\+84)(3|5|7|8|9)\d{8}$/;console.log(phoneRegex.test('0912345678'));   // trueconsole.log(phoneRegex.test('+84912345678')); // trueconsole.log(phoneRegex.test('12345'));        // false

Đây là mẫu đơn giản để minh họa, thực tế đầu số có thể thay đổi nên khi làm sản phẩm thật hãy kiểm tra theo quy định hiện hành hoặc dùng thư viện chuyên dụng.

Lấy ngày từ chuỗi

# Pythonimport retext = "Hạn nộp bài: 2025-03-14, nhắc lại vào 2025-03-10"dates = re.findall(r"\d{4}-\d{2}-\d{2}", text)print(dates)   # ['2025-03-14', '2025-03-10']

Dùng nhóm bắt có tên

import rem = re.match(r"(?P<user>[\w.]+)@(?P<domain>[\w.]+)", "an.nguyen@example.com")print(m.group("user"))    # an.nguyenprint(m.group("domain"))  # example.com

Mẹo để regex dễ đọc và ít lỗi

  1. Xây từng phần nhỏ: bắt đầu bằng mẫu đơn giản, thử, rồi thêm dần từng điều kiện.
  2. Dùng công cụ trực quan: các trang thử regex trực tuyến giải thích từng phần và hiện nhóm bắt, rất tiện cho việc học và gỡ lỗi.
  3. Chia nhỏ và đặt tên: lưu từng phần vào biến có tên rồi ghép lại thay vì một chuỗi dài.
  4. Dùng chế độ giãn (verbose): Python có re.VERBOSE cho phép viết regex nhiều dòng kèm chú thích.
  5. Dùng chuỗi thô (raw string): r"..." trong Python để không phải nhân đôi dấu gạch chéo ngược.
  6. Neo đầu cuối khi kiểm tra: dùng ^ và $ để toàn bộ chuỗi phải khớp, tránh khớp một phần.
  7. Test với cả trường hợp đúng và sai: gồm chuỗi rỗng, ký tự lạ, chuỗi rất dài.
import rephone = re.compile(r"""^(?:0|\+84)     # đầu số quốc gia hoặc số 0[35789]          # đầu số nhà mạng\d{8}$           # 8 chữ số còn lại""", re.VERBOSE)

Cạm bẫy cần tránh

  • Quên escape ký tự đặc biệt như . * + ? ( ) [ ] { } | \ ^ $ khi muốn khớp chính chúng.
  • Dùng regex cho thứ không phù hợp: phân tích HTML hay JSON phức tạp nên dùng bộ phân tích (parser) chuyên dụng.
  • Regex kiểm tra email quá "hoàn hảo": định dạng email hợp lệ rất phức tạp. Thường chỉ cần kiểm tra cơ bản rồi gửi email xác nhận để chắc chắn.
  • Backtracking thảm họa: một số mẫu lồng lượng từ (như (a+)+) có thể làm chương trình treo với chuỗi đầu vào xấu. Cẩn thận khi áp dụng regex lên dữ liệu do người dùng gửi lên.

Kết luận

Bạn không cần thuộc hết cú pháp regex. Hãy nắm các khối cơ bản, xây từng bước nhỏ, kiểm thử với công cụ trực quan và đừng ngại viết chú thích cho chính mình. Regex dùng đúng chỗ sẽ tiết kiệm rất nhiều dòng code.

Nếu bạn muốn luyện xử lý chuỗi và nhiều kỹ năng lập trình khác qua bài tập, hãy xem thêm trên codebem.com.

author_photo
Nguyễn Đình Cường

0 comment