Post

Regex

Regex

Regex là gì?

Regex (viết tắt của Regular Expression) nghĩa là biểu thức chính quy hoặc mẫu biểu thức chính quy.


Regex dùng để làm gì?

Regex là một chuổi ký tự bao gồm ký tự thường và ký tự đặc biệt được dùng để:

  • Tìm kiếm theo mẫu (pattern).
  • Kiểm tra dữ liệu có đúng định dạng không?
  • Thay thế dữ liệu theo mẫu.

Regex thường xuất hiện ở đâu?

Regex được sử dụng rất rộng rải và thường được sử dụng hằng ngày trong lập trình cũng như các công cụ lập trình như:

  • Các ngôn ngữ lập trình .NET, Java, JavaScript, Python, …
  • Trong xử lý dữ liệu SQL, file văn bản.
  • Trong các công cụ như VSCode, Visual Studio, Notpad++, grep, Vim, ..

Nguyên tắc hoạt động của Regex

  • Tạo một pattern, pattern có thể bao gồm các ký tự thường và ký tự đặc biệt.
  • Khi Regex chạy, trình thông dịch (regex engine) sẽ quét qua từng ký tự và đối chiếu với pattern bên trên.
    • Nếu chuỗi phù hợp với pattern,thì gọi là khớp match
    • Nếu chuỗi không khớp với pattern, thì regex engine sẽ trả về không khớp no match

So sánh sử dụng Regex với sử dụng vòng lặp

Bảng so sánh ưu, nhược điểm khi sử dụng Regex

Tiêu chíƯu điểm (Regex)Nhược điểm (Regex)
Tính ngắn gọnViết rất ngắn gọn, chỉ vài ký tự có thể biểu diễn pattern phức tạpRegex phức tạp dễ gây khó đọc, khó bảo trì
Tính biểu đạtDiễn đạt điều kiện kiểm tra rất mạnh mẽ, súc tíchNgười mới học khó hiểu cú pháp
Tính chuẩn hoáChuẩn dùng chung đa ngôn ngữ (Java, .NET, Python, …)Mỗi ngôn ngữ có thể có vài khác biệt nhỏ, dễ nhầm lẫn
Hiệu suấtTốt với pattern đơn giản, có thư viện tối ưuVới pattern phức tạp, nhiều backtracking → có thể chậm, tốn CPU
Xử lý phức tạpHỗ trợ lookahead, lookbehind, backreference mạnh mẽRất khó debug nếu lỗi logic
Tính mở rộngDễ mở rộng, chỉ thay đổi patternPattern dài quá gây khó khăn khi mở rộng logic phức tạp hơn (nếu có điều kiện nhiều bước)
Linh hoạt về logicMatch pattern cực tốtKhông phù hợp để viết các quy trình xử lý điều kiện nhiều bước, rẽ nhánh phức tạp
Tính học tậpMột khi đã học thành thạo → cực kỳ mạnhCần thời gian học và luyện tập

Bảng so sánh ưu, nhược điểm khi sử dụng vòng lặp

Tiêu chíƯu điểm (vòng lặp)Nhược điểm (vòng lặp)
Tính rõ ràngCode dễ đọc, dễ hiểu, ai cũng có thể nắm bắtDễ dài dòng nếu pattern phức tạp
Dễ debugDễ in log, dễ kiểm tra từng bướcCode nhiều bước nhỏ → dễ bỏ sót lỗi logic
Kiểm soát logicLinh hoạt xử lý nhiều bước, rẽ nhánh, gọi hàm phụViết lặp đi lặp lại các thao tác “match” thủ công
Tính mở rộngRất thuận lợi khi thêm điều kiện nghiệp vụ phức tạpKhó tái sử dụng như 1 pattern tổng quát
Hiệu suấtChủ động kiểm soát tối ưu (thuật toán chạy tuyến tính, không lo backtracking)Nếu không tối ưu vẫn có thể chậm, nhất là với chuỗi rất lớn
Tính học tậpAi cũng quen thuộc, học nhanhKhông giúp rèn luyện kỹ năng pattern matching như regex
Tính biểu đạtRõ ràng từng bước xử lýKhó súc tích khi pattern nhiều điều kiện, dễ rối
Độ chuẩn hoáKhông phụ thuộc vào engine regex, chạy giống nhau ở mọi ngôn ngữKhông có chuẩn pattern “chung” như regex

Bảng so sánh khi sử dụng Regex và vòng lặp

 RegexVòng lặp
Ngắn gọn
Dễ đọc
Dễ bảo trì
Mạnh trong match phức tạp
Linh hoạt nhiều bước
Hiệu suất với pattern đơn giản
Hiệu suất với pattern phức tạpcó thể kémtốt hơn

Khi nào thì sử dụng Regex và khi nào thì sử dụng vòng lặp

  • Pattern phức tạp -> dùng Regex.
  • Logic phức tạp -> dùng vòng lặp.
  • Trong một số trường hợp có thể kết hợp cả hai, xử lý pattern phức tạp với Regex trước sau đó dùng vòng lặp để xử lý logic phức tạp sau.

Bảng liệt kê các ký tự Regex phổ biến trong .NET (tương thích với System.Text.RegularExpressions)

Ký tựÝ nghĩa  
.Khớp bất kỳ ký tự nào (trừ newline \n)  
^Khớp đầu chuỗi  
$Khớp cuối chuỗi  
*Lặp 0 hoặc nhiều lần  
+Lặp 1 hoặc nhiều lần  
?Lặp 0 hoặc 1 lần  
{n}Lặp đúng n lần  
{n,}Lặp ít nhất n lần  
{n,m}Lặp từ n đến m lần  
[]Tập hợp ký tự  
[^]Tập hợp phủ định  
` | `Hoặc (`a | b`)  
()Nhóm (group)  
\Escape ký tự đặc biệt, ví dụ \.  
\dChữ số [0-9]  
\DKhông phải chữ số  
\wKý tự chữ + số + _  
\WKhông phải ký tự chữ + số + _  
\sKhoảng trắng  
\SKhông phải khoảng trắng  
\bRanh giới từ (word boundary)  
\BKhông phải ranh giới từ  
(?i)Bật ignore case  
(?-i)Tắt ignore case  
(?m)Bật multiline (^$ áp dụng cho mỗi dòng)  
(?s)Bật singleline (chấm . khớp cả \n)  
(?=X)Positive lookahead  
(?!X)Negative lookahead  
(?<=X)Positive lookbehind  
(?<!X)Negative lookbehind  
(?<name>...)Group đặt tên  
\k<name>Backreference theo tên nhóm  
(?<number>...)Group đặt tên number  
\k<number>Backreference theo tên number  
(?<quote>['"])Group đặt tên quote khớp dấu nháy đơn hoặc đôi  
`(?...) | (?...)\`hai group đặt tên khác nhau  
\ABắt đầu chuỗi  
\ZKết thúc chuỗi  
\GNối tiếp match trước đó  

✅ .NET Regex hỗ trợ rất mạnh, ngoài ra bạn còn có thể sử dụng RegexOptions khi gọi Regex.Match hoặc Regex.IsMatch để điều chỉnh behavior (ví dụ ignore case, multiline, culture invariant).

This post is licensed under CC BY 4.0 by the author.