Biểu thức chính quy (std::regex)
Biểu thức chính quy (regular expression - regex) là một cách mô tả mẫu (pattern) để tìm kiếm, kiểm tra, hoặc thay thế văn bản. C++ hỗ trợ regex thông qua thư viện chuẩn <regex> (từ C++11).
Kiểm tra chuỗi khớp mẫu với std::regex_match
Phần tiêu đề “Kiểm tra chuỗi khớp mẫu với std::regex_match”#include <regex>#include <iostream>#include <string>
int main() { std::regex pattern(R"(\w+@\w+\.\w+)"); // R"(...)" là raw string, tránh phải escape dấu \
if (std::regex_match(email, pattern)) { std::cout << "Email hop le" << std::endl; } else { std::cout << "Email khong hop le" << std::endl; }
return 0;}std::regex_match kiểm tra xem toàn bộ chuỗi có khớp hoàn toàn với mẫu hay không.
Tìm kiếm mẫu bên trong chuỗi với std::regex_search
Phần tiêu đề “Tìm kiếm mẫu bên trong chuỗi với std::regex_search”#include <regex>#include <iostream>#include <string>
int main() { std::regex phone_pattern(R"(\d{10})"); // Tìm dãy đúng 10 chữ số
std::smatch match; // Lưu kết quả khớp if (std::regex_search(text, match, phone_pattern)) { std::cout << "Tim thay so dien thoai: " << match.str() << std::endl; }
return 0;}Khác với regex_match, regex_search chỉ cần tìm thấy mẫu ở đâu đó trong chuỗi, không yêu cầu khớp toàn bộ.
Tìm tất cả các kết quả khớp
Phần tiêu đề “Tìm tất cả các kết quả khớp”#include <regex>#include <iostream>#include <string>
int main() { std::string text = "So dien thoai: 0912345678, 0987654321"; std::regex pattern(R"(\d{10})");
auto begin = std::sregex_iterator(text.begin(), text.end(), pattern); auto end = std::sregex_iterator();
for (auto it = begin; it != end; ++it) { std::cout << it->str() << std::endl; } // 0912345678 // 0987654321
return 0;}Thay thế văn bản với std::regex_replace
Phần tiêu đề “Thay thế văn bản với std::regex_replace”#include <regex>#include <iostream>#include <string>
int main() { std::string text = "Ngay hom nay la 2024-01-15"; std::regex date_pattern(R"((\d{4})-(\d{2})-(\d{2}))");
// $1, $2, $3 tham chiếu đến các nhóm bắt (capture group) trong ngoặc đơn std::string result = std::regex_replace(text, date_pattern, "$3/$2/$1");
std::cout << result << std::endl; // Ngay hom nay la 15/01/2024
return 0;}Một số ký hiệu regex thường dùng
Phần tiêu đề “Một số ký hiệu regex thường dùng”| Ký hiệu | Ý nghĩa |
|---|---|
\d |
Một chữ số (0-9) |
\w |
Một ký tự chữ, số, hoặc gạch dưới |
\s |
Khoảng trắng |
. |
Bất kỳ ký tự nào |
+ |
Một hoặc nhiều lần |
* |
Không hoặc nhiều lần |
? |
Không hoặc một lần |
{n} |
Đúng n lần |
() |
Nhóm bắt (capture group) |
Vì sao dùng raw string R"(...)" với regex?
Phần tiêu đề “Vì sao dùng raw string R"(...)" với regex?”Regex thường dùng nhiều dấu \ (ví dụ \d, \w), mà trong chuỗi C++ thông thường, \ cần được escape thành \\. Raw string R"(...)" (C++11) cho phép viết dấu \ trực tiếp mà không cần escape, giúp mẫu regex dễ đọc hơn nhiều:
std::regex normal("\\d{3}-\\d{4}"); // Chuỗi thường - phải escape mỗi \std::regex raw(R"(\d{3}-\d{4})"); // Raw string - viết trực tiếp, dễ đọc hơnTổng kết
Phần tiêu đề “Tổng kết”<regex>cung cấp công cụ xử lý biểu thức chính quy trong C++, từ C++11regex_match: kiểm tra toàn bộ chuỗi có khớp mẫu;regex_search: tìm mẫu ở bất kỳ đâu trong chuỗiregex_replace: thay thế các phần khớp mẫu bằng nội dung khác, có thể dùng$1,$2… để tham chiếu đến nhóm bắt- Nên dùng raw string
R"(...)"khi viết mẫu regex để tránh phải escape dấu\liên tục