在 C++ 中,正則表達式(regex)是一種用于匹配字符串模式的強大工具。正則表達式不僅能幫助你查找符合特定模式的字符,還能捕獲匹配的子字符串(即分組捕獲)。這篇文章將介紹 C++ 正則表達式中的分組捕獲機制,并提供多個示例代碼來幫助你快速入門。
一、基本概念:正則表達式分組捕獲
正則表達式分組捕獲是一種能夠將匹配的部分提取出來的技術。在 C++ 中,正則表達式分組捕獲通常通過小括號 ()
來實現。每個分組會捕獲匹配到的子字符串,并且可以在代碼中通過相應的索引訪問它們。
分組的基本語法
()
:用于定義捕獲分組。你可以在正則表達式中使用多個分組,C++ 中從1
開始對分組編號。
示例:簡單分組捕獲
假設我們需要從一個日期字符串中提取年月日,可以使用正則表達式中的分組捕獲來實現。
二、C++ 正則表達式庫:<regex>
在 C++ 中使用正則表達式時,需要包含頭文件 <regex>
。基本的正則表達式操作包括:
std::regex
:正則表達式對象。std::smatch
:保存匹配結果的對象。std::regex_search
:查找匹配。std::regex_match
:完全匹配整個字符串。std::regex_replace
:替換匹配的字符串。
三、示例代碼:日期分組捕獲
我們可以編寫一個示例程序,從一個字符串中提取出日期的年、月和日。
示例 1:提取日期(YYYY-MM-DD
)
假設我們有一個日期字符串 2023-02-25
,并希望通過正則表達式捕獲出年、月、日。
#include <iostream>
#include <regex>
#include <string>int main() {std::string input = "2023-02-25";// 正則表達式:捕獲年、月和日std::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");std::smatch matches;// 如果匹配成功if (std::regex_match(input, matches, pattern)) {// 輸出捕獲的各個分組std::cout << "Year: " << matches[1] << std::endl;std::cout << "Month: " << matches[2] << std::endl;std::cout << "Day: " << matches[3] << std::endl;} else {std::cout << "No match found." << std::endl;}return 0;
}
代碼解析:
-
正則表達式
R"((\d{4})-(\d{2})-(\d{2}))"
:
(\d{4})
捕獲4位數字(即年份)。(\d{2})
捕獲2位數字(即月份和日期)。
-
matches[1]
、matches[2]
、matches[3]
分別存儲匹配到的年份、月份和日期。
輸出:
Year: 2023
Month: 02
Day: 25
四、捕獲多個匹配
有時我們需要從文本中查找多個匹配項。std::regex_search
可以用于查找匹配,但它只會找到第一個匹配項。如果你想捕獲所有匹配項,可以使用 std::regex_iterator
。
示例 2:提取所有匹配的日期
假設我們有一段文本,其中包含多個日期,我們希望提取所有日期。
#include <iostream>
#include <regex>
#include <string>
#include <iterator>int main() {std::string input = "The event will be held on 2023-02-25, followed by another on 2024-03-01.";// 正則表達式:捕獲日期std::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");std::smatch matches;// 使用 regex_iterator 查找所有匹配auto begin = std::sregex_iterator(input.begin(), input.end(), pattern);auto end = std::sregex_iterator();for (auto it = begin; it != end; ++it) {std::cout << "Found date: " << it->str() << std::endl;}return 0;
}
輸出:
Found date: 2023-02-25
Found date: 2024-03-01
使用 std::regex_search
來查找日期的所有匹配
#include <iostream>
#include <regex>
#include <string>int main() {std::string input = "The event will be held on 2023-02-25, followed by another on 2024-03-01.";// 正則表達式:捕獲日期std::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");std::smatch matches;// 使用 cbegin 和 cend 來獲取常量迭代器auto begin = input.cbegin();while (std::regex_search(begin, input.cend(), matches, pattern)) {// 輸出匹配到的日期std::cout << "Found date: " << matches[0] << std::endl;// 更新搜索起始位置,繼續從上一個匹配位置之后開始搜索begin = matches[0].second;}return 0;
}
輸出:
Found date: 2023-02-25
Found date: 2024-03-01
五、捕獲和替換(regex_replace
)
正則表達式不僅可以用于查找和捕獲,還可以用于替換匹配的內容。通過 std::regex_replace
,你可以將捕獲到的內容替換成新的內容。
示例 3:替換日期格式
假設我們希望將日期格式從 YYYY-MM-DD
更改為 DD/MM/YYYY
。
#include <iostream>
#include <regex>
#include <string>int main() {std::string input = "The event will be held on 2023-02-25, and another on 2024-03-01.";// 正則表達式:捕獲日期std::regex pattern(R"((\d{4})-(\d{2})-(\d{2}))");// 使用 regex_replace 將日期格式替換為 DD/MM/YYYYstd::string output = std::regex_replace(input, pattern, R"($3/$2/$1)");std::cout << "Updated text: " << output << std::endl;return 0;
}
輸出:
Updated text: The event will be held on 25/02/2023, and another on 01/03/2024.
六、進階應用:捕獲多個分組
當正則表達式中有多個分組時,你可以通過 matches[n]
訪問每個分組的捕獲結果。
示例 4:捕獲多個分組(例如,提取姓名和年齡)
#include <iostream>
#include <regex>
#include <string>int main() {std::string input = "John Doe, Age: 30; Jane Smith, Age: 25";// 正則表達式:捕獲姓名和年齡std::regex pattern(R"((\w+ \w+), Age: (\d+))");std::smatch matches;// 查找匹配auto begin = std::sregex_iterator(input.begin(), input.end(), pattern);auto end = std::sregex_iterator();for (auto it = begin; it != end; ++it) {std::cout << "Name: " << it->str(1) << ", Age: " << it->str(2) << std::endl;}return 0;
}
輸出:
Name: John Doe, Age: 30
Name: Jane Smith, Age: 25
七、總結
正則表達式的分組捕獲是一個非常強大的工具,它能夠讓你輕松提取和操作字符串中的特定部分。C++ 中的 <regex>
庫提供了靈活的接口,允許你使用正則表達式進行模式匹配、捕獲分組、查找多個匹配項以及進行替換操作。通過本文的示例代碼,希望你能掌握 C++ 中正則表達式分組捕獲的基礎應用,并能在實際項目中靈活使用正則表達式來處理文本數據。