C++11 標準庫引入 <regex>,提供強大、標準化的正規表示式支援,取代 Boost.Regex 等第三方庫。本文以實際 HTML 片段處理為例,示範搜尋、替換、多重匹配等核心用法。
| 類別/函式 | 用途 |
|---|---|
std::regex | 編譯正規表示式模式 |
std::smatch | 匹配結果容器(string 專用) |
std::regex_search | 搜尋第一個匹配 |
std::regex_replace | 替換所有匹配 |
std::sregex_iterator | 迭代所有匹配 |
std::string html =
"<p><img src=\"D:\\DOC\\...\\main.png\" width=\"30%\" height=\"30%\"></p>"
"<ol><li></li><li>中文歌</li><li></li><li>xxx</li><li></li></ol>"
"<p><img src=\"D:\\DOC\\...\\main-about.png\" ...></p>"
"<ol><li></li><li>xxxxx</li><li></li></ol>"
"<p><img src=\"D:\\DOC\\...\\main-setting.png\" ...></p>";
// 模式:捕獲群組 1=std::regex img_regex(R"(( ]*src=["'])[^"']*\\(images\\[^"']*["'][^>]*>))"); std::string rep = "$1$3"; // 保留群組 1 與 3,丟棄中間絕對路徑 std::string result = std::regex_replace(html, img_regex, rep);
輸出:所有 src 變為 images\main\main.png 等相對路徑。
<img> 標籤std::regex tag_regex(R"(]*>)"); std::smatch match; if (std::regex_search(html, match, tag_regex)) std::cout << match[0] << '\n'; // 輸出第一個完整 img 標籤
<img> 標籤auto begin = std::sregex_iterator(html.begin(), html.end(), tag_regex);
auto end = std::sregex_iterator();
for (auto it = begin; it != end; ++it) {
std::cout << it->str() << '\n'; // 依序輸出 3 個 img 標籤
}
#include <regex>
#include <string>
#include <iostream>
int main() {
std::string html =
"<p><img src=\"D:\\\\DOC\\\\...\\\\main.png\" width=\"30%\" height=\"30%\"></p>"
"<ol><li></li><li>中文歌</li><li></li><li>xxx</li><li></li></ol>"
"<p><img src=\"D:\\\\DOC\\\\...\\\\main-about.png\" width=\"30%\" height=\"30%\"></p>"
"<ol><li></li><li>xxxxx</li><li></li></ol>"
"<p><img src=\"D:\\\\DOC\\\\...\\\\main-setting.png\" width=\"30%\" height=\"30%\"></p>";
// 替換展示
std::regex img_regex(R"((
]*src=["'])[^"']*\\(images\\[^"']*["'][^>]*>))");
std::cout << "=== Replace ===\n" << std::regex_replace(html, img_regex, "$1$3") << "\n\n";
// 搜尋第一個
std::regex tag_regex(R"(
]*>)");
std::smatch match;
std::cout << "=== First match ===\n";
if (std::regex_search(html, match, tag_regex))
std::cout << match[0] << "\n\n";
// 迭代所有
std::cout << "=== All matches ===\n";
for (auto it = std::sregex_iterator(html.begin(), html.end(), tag_regex);
it != std::sregex_iterator(); ++it)
std::cout << it->str() << "\n";
return 0;
}
R"(...)" 避免雙重跳脫,提升可讀性std::regex_error,建議包裝 try-catchstd::regex 建構較昂貴,重複使用時應複用物件std::regex::extended 等標準regex_replace 會複製整個字串,考慮串流處理或手寫解析器| 模式 | 說明 |
|---|---|
\d | 數字 |
\w | 字母數字底線 |
\s | 空白字元 |
. | 任意字元(除換行) |
* + ? | 0或多 / 1或多 / 0或1 |
^ $ | 行首 / 行尾 |
(...) | 捕獲群組 |
(?:...) | 非捕獲群組 |
| | 或 |
<regex> 讓 C++ 終於擁有標準化、型別安全的正規表示式能力。掌握 regex_search、regex_replace、sregex_iterator 三大核心工具,即可應對 90% 字串處理需求,告別手寫解析器的痛苦。