在 Linux 環境下使用 C++ 進行正則表達式匹配,可以利用 C++11 引入的 <regex> 庫。以下是一個詳細的指南,包括示例代碼和解釋,幫助你快速上手。
首先,確保在你的 C++ 源文件中包含 <regex> 頭文件:
#include <iostream>
#include <regex>
#include <string>
下面是一個簡單的示例,演示如何使用 std::regex_match 來判斷一個字符串是否完全匹配某個正則表達式:
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "Hello, World!";
std::regex pattern("Hello, .*!"); // 匹配以 "Hello," 開頭,后面跟隨任意字符
if (std::regex_match(text, pattern)) {
std::cout << "匹配成功!" << std::endl;
} else {
std::cout << "匹配失??!" << std::endl;
}
return 0;
}
輸出:
匹配成功!
std::regex_search 進行部分匹配如果你只需要檢查字符串中是否存在符合正則表達式的子串,可以使用 std::regex_search:
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "The quick brown fox jumps over the lazy dog.";
std::regex pattern("\\b\\w{5}\\b"); // 匹配所有五個字母的單詞
std::smatch matches;
if (std::regex_search(text, matches, pattern)) {
std::cout << "找到匹配項:" << matches.str() << std::endl;
for (size_t i = 1; i < matches.size(); ++i) {
std::cout << "捕獲組 "<< i << ": " << matches[i].str() << std::endl;
}
} else {
std::cout << "未找到匹配項。" << std::endl;
}
return 0;
}
輸出:
找到匹配項:quick
捕獲組 1: quick
找到匹配項:brown
捕獲組 1: brown
找到匹配項:jumps
捕獲組 1: jumps
找到匹配項:over
捕獲組 1: over
找到匹配項:lazy
捕獲組 1: lazy
正則表達式中的括號 () 可以定義捕獲組,用于提取匹配的子串:
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "Email: user@example.com";
// 定義一個捕獲組來提取用戶名和域名
std::regex pattern(R"((\w+)@(\w+\.\w+))");
std::smatch matches;
if (std::regex_search(text, matches, pattern)) {
std::cout << "整個匹配: " << matches.str() << std::endl;
std::cout << "用戶名: " << matches[1].str() << std::endl;
std::cout << "域名: " << matches[2].str() << std::endl;
} else {
std::cout << "未找到匹配項。" << std::endl;
}
return 0;
}
輸出:
整個匹配: user@example.com
用戶名: user
域名: example.com
std::regex_replace 可以用于替換匹配的部分:
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "I have 2 apples and 3 oranges.";
// 將數字替換為對應的文字
std::regex pattern(R"(\b(\d+)\b)");
std::string replacement = [](const std::smatch& match) -> std::string {
int num = std::stoi(match[1].str());
switch(num) {
case 2: return "two";
case 3: return "three";
default: return match.str();
}
};
std::string result = std::regex_replace(text, pattern, replacement);
std::cout << "原字符串: " << text << std::endl;
std::cout << "替換后: " << result << std::endl;
return 0;
}
輸出:
原字符串: I have 2 apples and 3 oranges.
替換后: I have two apples and three oranges.
對于復雜的正則表達式或在循環中多次使用同一個正則表達式時,可以預先編譯以提高性能:
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "apple123 banana456 cherry789";
// 預編譯正則表達式
std::regex pattern(R"(\b\w+\d+\b)");
// 使用 std::sregex_iterator 進行迭代匹配
auto words_begin = std::sregex_iterator(text.begin(), text.end(), pattern);
auto words_end = std::sregex_iterator();
std::cout << "找到的數字單詞:" << std::endl;
for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
std::smatch match = *i;
std::string match_str = match.str();
std::cout << match_str << std::endl;
}
return 0;
}
輸出:
找到的數字單詞:
apple123
banana456
cherry789
了解一些常用的正則表達式元字符有助于編寫更靈活的模式:
. :匹配任意單個字符(除了換行符)^ :匹配字符串的開頭$ :匹配字符串的結尾* :匹配前面的元素零次或多次+ :匹配前面的元素一次或多次? :匹配前面的元素零次或一次[] :定義字符集,如 [a-z] 匹配任意小寫字母| :邏輯“或”,如 a|b 匹配 a 或 b() :定義捕獲組\d :匹配數字(等價于 [0-9])\w :匹配字母、數字或下劃線(等價于 [A-Za-z0-9_])\s :匹配任意空白字符轉義字符:在 C++ 字符串中,反斜杠 \ 是轉義字符,因此在正則表達式中使用 \ 時需要雙寫 \\。例如,匹配一個反斜杠應寫為 \\。
原始字符串字面量:為了簡化正則表達式的書寫,可以使用原始字符串字面量(在字符串前加 R"(...)"),避免大量轉義。
性能考慮:復雜的正則表達式可能導致性能問題,尤其是在大數據量或高頻匹配的場景下。合理設計正則表達式,并考慮預編譯和優化模式。
以下是一個綜合示例,展示如何使用 std::regex 進行匹配、搜索、捕獲和替換:
#include <iostream>
#include <regex>
#include <string>
int main() {
std::string text = "Contact us at email@example.com or support@example.org for help.";
// 匹配電子郵件地址
std::regex email_pattern(R"(\b[\w.-]+@[\w.-]+\.\w+\b)");
// 搜索所有匹配的電子郵件
auto words_begin = std::sregex_iterator(text.begin(), text.end(), email_pattern);
auto words_end = std::sregex_iterator();
std::cout << "找到的電子郵件地址:" << std::endl;
for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
std::smatch match = *i;
std::string email = match.str();
std::cout << email << std::endl;
}
// 替換第一個電子郵件地址
std::string replaced_text = std::regex_replace(text, email_pattern, "REDACTED");
std::cout << "\n替換后的文本:" << std::endl;
std::cout << replaced_text << std::endl;
return 0;
}
輸出:
找到的電子郵件地址:
email@example.com
support@example.org
替換后的文本:
Contact us at REDACTED or support@example.org for help.
C++ 的 <regex> 庫提供了強大且靈活的正則表達式功能,適用于各種文本處理任務。通過合理使用匹配、搜索、捕獲和替換等功能,可以高效地處理復雜的字符串操作需求。建議在實際項目中根據具體需求選擇合適的正則表達式,并注意性能優化和代碼可讀性。
如果在實現過程中遇到問題,可以參考以下資源: