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
- Nếu chuỗi phù hợp với pattern,thì gọi là khớp
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ọn | Viết rất ngắn gọn, chỉ vài ký tự có thể biểu diễn pattern phức tạp | Regex phức tạp dễ gây khó đọc, khó bảo trì |
Tính biểu đạt | Diễn đạt điều kiện kiểm tra rất mạnh mẽ, súc tích | Ngườ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ất | Tốt với pattern đơn giản, có thư viện tối ưu | Với pattern phức tạp, nhiều backtracking → có thể chậm, tốn CPU |
Xử lý phức tạp | Hỗ trợ lookahead, lookbehind, backreference mạnh mẽ | Rất khó debug nếu lỗi logic |
Tính mở rộng | Dễ mở rộng, chỉ thay đổi pattern | Pattern 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ề logic | Match pattern cực tốt | Khô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ập | Một khi đã học thành thạo → cực kỳ mạnh | Cầ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àng | Code dễ đọc, dễ hiểu, ai cũng có thể nắm bắt | Dễ dài dòng nếu pattern phức tạp |
Dễ debug | Dễ in log, dễ kiểm tra từng bước | Code nhiều bước nhỏ → dễ bỏ sót lỗi logic |
Kiểm soát logic | Linh 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ộng | Rất thuận lợi khi thêm điều kiện nghiệp vụ phức tạp | Khó tái sử dụng như 1 pattern tổng quát |
Hiệu suất | Chủ độ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ập | Ai cũng quen thuộc, học nhanh | Không giúp rèn luyện kỹ năng pattern matching như regex |
Tính biểu đạt | Rõ 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
Regex | Vò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ạp | có thể kém | tố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ụ \. | ||
\d | Chữ số [0-9] | ||
\D | Không phải chữ số | ||
\w | Ký tự chữ + số + _ | ||
\W | Không phải ký tự chữ + số + _ | ||
\s | Khoảng trắng | ||
\S | Không phải khoảng trắng | ||
\b | Ranh giới từ (word boundary) | ||
\B | Không phải ranh giới từ | ||
(?i) | Bật ignore case | ||
(?-i) | Tắt ignore case | ||
(?m) | Bật multiline (^ và $ á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 | ||
\A | Bắt đầu chuỗi | ||
\Z | Kết thúc chuỗi | ||
\G | Nố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.