C++ 中的正則表達式(Regular Expression)主要通過標準庫 <regex>
提供,能夠用于字符串匹配、查找、替換、驗證格式等。它在 C++11 中首次引入,并在 C++14 和 C++17 中逐步完善。
一、頭文件和命名空間
#include <regex>
#include <string>
#include <iostream>using namespace std;
二、主要類介紹
類名 | 功能描述 |
---|---|
std::regex | 用于存儲正則表達式模式 |
std::smatch | 用于存儲匹配結果(string 匹配) |
std::cmatch | 用于存儲匹配結果(C字符串匹配) |
std::regex_match | 判斷整個字符串是否匹配正則模式 |
std::regex_search | 判斷字符串中是否有匹配正則的部分 |
std::regex_replace | 替換匹配的字符串內容 |
三、常見正則表達式語法
正則語法 | 含義 | |
---|---|---|
. | 匹配任意單個字符 | |
* | 匹配前面的字符 0 次或多次 | |
+ | 匹配前面的字符 1 次或多次 | |
? | 匹配前面的字符 0 次或 1 次 | |
^ | 匹配字符串開頭 | |
$ | 匹配字符串結尾 | |
[] | 匹配方括號內任一字符 | |
` | ` | 或運算符 |
() | 子表達式分組 | |
\d | 數字 | |
\w | 單詞字符(字母/數字/下劃線) | |
\s | 空白字符 |
四、示例代碼
1. 使用 regex_match
完全匹配
string s = "abc123";
regex pattern("[a-z]+\\d+"); // 小寫字母 + 數字if (regex_match(s, pattern)) {cout << "完全匹配成功" << endl;
} else {cout << "匹配失敗" << endl;
}
2. 使用 regex_search
局部匹配
string s = "hello 123 world";
regex pattern("\\d+"); // 匹配數字smatch result;
if (regex_search(s, result, pattern)) {cout << "找到數字:" << result.str() << endl;
}
3. 使用 regex_replace
字符替換
string s = "abc123xyz456";
regex pattern("\\d+"); // 匹配數字string replaced = regex_replace(s, pattern, "#");
cout << replaced << endl; // 輸出:abc#xyz#
4. 捕獲多個子匹配
string s = "Name: John, Age: 25";
regex pattern("Name: (\\w+), Age: (\\d+)");smatch match;
if (regex_search(s, match, pattern)) {cout << "姓名:" << match[1] << endl;cout << "年齡:" << match[2] << endl;
}
5. 匹配郵箱格式示例
string email = "user123@example.com";
regex pattern("[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}");if (regex_match(email, pattern)) {cout << "郵箱格式合法" << endl;
} else {cout << "郵箱格式錯誤" << endl;
}
五、匹配模式(flag)
正則對象可以設置模式:
regex pattern("abc", regex_constants::icase); // 忽略大小寫
常用標志位:
標志名 | 含義 |
---|---|
regex_constants::icase | 忽略大小寫 |
regex_constants::ECMAScript | 默認模式,支持現代語法 |
regex_constants::basic | 基本正則 |
regex_constants::extended | 擴展正則(如 POSIX) |
六、性能提示
regex
在 C++11 初期實現性能一般,現代編譯器已優化。- 對于頻繁匹配,可復用
std::regex
對象,避免重復構造。 - 若性能要求極高,可考慮
RE2
等替代庫(Google)。
七、綜合實戰示例
下面以為 日志過濾、文件名匹配 和 表單驗證 的完整 C++ 正則表達式示例,每個都附詳細解釋,幫助大家實際應用。
1、日志過濾:提取指定格式的日志(如錯誤信息)
目標:從日志中提取 [ERROR]
級別的信息
#include <iostream>
#include <regex>
#include <string>
#include <vector>using namespace std;int main() {vector<string> logs = {"[INFO] 2025-07-14 Connection established","[ERROR] 2025-07-14 Disk not found","[WARN] 2025-07-14 High memory usage","[ERROR] 2025-07-14 Timeout occurred"};regex error_pattern(R"(\[ERROR\]\s+(\d{4}-\d{2}-\d{2})\s+(.*))");for (const auto& log : logs) {smatch match;if (regex_match(log, match, error_pattern)) {cout << "日期: " << match[1] << ", 錯誤信息: " << match[2] << endl;}}return 0;
}
輸出:
日期: 2025-07-14, 錯誤信息: Disk not found
日期: 2025-07-14, 錯誤信息: Timeout occurred
2、文件名匹配:匹配特定后綴的文件(如 .txt
、.log
)
#include <iostream>
#include <regex>
#include <vector>using namespace std;int main() {vector<string> filenames = {"report.txt", "data.csv", "log_2025.log", "notes.TXT", "script.cpp"};regex txt_log_pattern(R"((.*)\.(txt|log))", regex_constants::icase); // 忽略大小寫cout << "匹配的文件名:" << endl;for (const auto& name : filenames) {if (regex_match(name, txt_log_pattern)) {cout << " " << name << endl;}}return 0;
}
輸出:
匹配的文件名:report.txtlog_2025.lognotes.TXT
3、表單驗證:驗證郵箱、手機號、密碼強度
1. 郵箱驗證
string email = "test_user-123@example.co.uk";
regex email_pattern(R"([\w\.-]+@[\w\.-]+\.[a-zA-Z]{2,})");cout << (regex_match(email, email_pattern) ? "郵箱合法" : "郵箱非法") << endl;
2. 手機號驗證(中國大陸)
string phone = "13812345678";
regex phone_pattern(R"(1[3-9]\d{9})"); // 以1開頭 + 合法段位 + 9位數字cout << (regex_match(phone, phone_pattern) ? "手機號合法" : "手機號非法") << endl;
3. 密碼強度驗證(8~16位,包含字母和數字)
string password = "Abc12345";
regex pwd_pattern(R"((?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,16})");cout << (regex_match(password, pwd_pattern) ? "密碼合法" : "密碼不合法") << endl;
4、總結與推薦實踐
場景 | 推薦正則 | |
---|---|---|
日志提取 | ^\[ERROR\].* 或帶時間戳的模式 | |
文件篩選 | `.*.(txt | log)$` |
郵箱驗證 | [\w\.-]+@[\w\.-]+\.[a-zA-Z]{2,} | |
手機號驗證 | 1[3-9]\d{9} | |
密碼驗證 | (?=.*[A-Za-z])(?=.*\d).{8,16} |