C++ 標準庫直到 C++11 才納入 <regex>,在此之前開發者依賴第三方庫。本文對比三大經典庫:**ATL CAtlRegExp**(輕量、內建 Visual Studio)、**GRETA**(Microsoft Research、模板化、效能極強)、**Boost.Regex**(功能最全、準標準庫),涵蓋語法支援、API 設計、編譯相依、效能基準與遷移建議。
正則語法速查(三庫通用核心子集)
| 元字符 | 意義 | 範例 |
. | 任意單一字元 | a.c 配合 "abc", "axc" |
[...] | 字元類別 | [aeiou] 配合任一母音 |
[^...] | 排除字元類別 | [^0-9] 非數字 |
^ | 行首 / 類別否定 | ^abc 以 abc 開頭 |
$ | 行尾 | xyz$ 以 xyz 結尾 |
| | 或 | cat|dog |
() | 分組/捕獲 | (\d+),(\d+) |
\ | 轉義 | \. 配合實際句點 |
? | 0 或 1 次 | \d{3}-?\d{4} |
+ | 1 次以上 | \w+ |
* | 0 次以上 | .* |
?? +? *? | 非貪婪版 | .*? 最短匹配 |
三大庫詳細對比
| 特性 | ATL CAtlRegExp | GRETA | Boost.Regex |
| 所需標頭 | <atlrx.h> | regexpr2.h + greta.lib | <boost/regex.hpp> |
| 相依庫 | 僅 ATL (VS 內建) | 單一 .lib + .h | Boost 庫 (Header-only 可選) |
| 語法風格 | 類 Perl、{...} 非捕獲群 | 類 Perl、(...) 捕獲群 | 完整 Perl/PCRE 相容 |
| Unicode 支援 | CAtlRegExp<WCHAR> | 僅 ANSI (舊版) | wregex 完整支援 |
| 替換功能 | 無內建 | substitute() | regex_replace |
| 分割字串 | 無 | 無 | regex_split / regex_token_iterator |
| 編譯速度 | 快 | 極快 | 較慢 (模板重) | 執行速度 (基準測試) > 基準 | **~7-10x 快於 ATL** | 基準 |
| 授權 | Microsoft EULA | Microsoft Research 共用原始碼 | Boost License (極鬆綁) |
程式碼範例:解析 URL
ATL CAtlRegExp
CAtlRegExp<> re;
REParseError err = re.Parse("({[^:/?#]+}:)?(//{[^/?#]*})?{[^?#]*}(\\?{[^#]*})?(#{.*})?");
CAtlREMatchContext<> mc;
if (re.Match("https://search.microsoft.com/us/Search.asp?q=atl#results", &mc)) {
for (UINT i=0; i
GRETA
using namespace regex;
match_results results;
rpattern pat("\\$(\\d+)(\\.(\\d\\d))?"); // $12.34
if (pat.match("The book cost $12.34", results)) {
cout << "price: " << results[0] << endl; // $12.34
cout << "dollars: " << results[1] << endl; // 12
cout << "cents: " << results[3] << endl; // 34
}
Boost.Regex
boost::regex re("(\\w+):(\\d+)");
std::string s = "port:8080";
boost::smatch m;
if (boost::regex_match(s, m, re)) {
cout << m[1] << "=" << m[2]; // port=8080
}
// 分割字串
std::list tokens;
boost::regex_split(std::back_inserter(tokens), "a,b,c", boost::regex(","));
// tokens = {"a","b","c"}
效能測試結論
- 測試模式:
^([0-9]+)(\-| |$)(.*)$ 對 "100- this is a line..."
- GRETA ≈ **7x Boost.Regex**,**10x ATL** (VS2003 編譯環境)。
- Boost.Regex 文件豐富、功能完整(語法高亮、分割、迭代器),適合功能導向專案。
- GRETA 輕量、極快、適合高頻解析熱點路徑(日誌分析、封包檢測)。
- C++11 起建議直接用
std::regex(底層多為 Boost 移植),避免額外相依。
「選擇正則庫的鐵律:功能夠用就選最輕的;需 Unicode/分割/替換/迭代器 → Boost/std::regex;極致效能熱點 → GRETA/RE2。」