在C++中利用正则表达式从字符串中获取数字内容
·
std::smatch 是 C++ 标准库中用于存储正则表达式匹配结果的容器类型。让我详细分析它的作用:
(1) smatch 是 std::match_results<std::string::const_iterator> 的类型别名
(2) 专门用于存储 std::string 的正则匹配结果
以下面这段代码为例:
std::string& filename;
std::regex number_regex(R"((\d+))");
std::smatch match;
if (std::regex_search(filename, match, number_regex)) {
try {
return std::stoi(match[1].str());
}
catch (...) {
return -1;
}
}
这段代码的作用是从文件名中提取第一个数字并返回。让我逐句解析:
std::string& filename; // 文件名的引用(作为参数传入)
std::regex number_regex(R"((\d+))");
// 创建正则表达式对象:
// \d+ : 匹配一个或多个数字
// () : 捕获组,保存匹配的数字
std::smatch match;
// 创建匹配结果容器(注意:你的代码中重复声明了两次)
if (std::regex_search(filename, match, number_regex)) {
// 在 filename 中搜索匹配 number_regex 的内容
// 如果找到,match 会保存匹配结果
try {
return std::stoi(match[1].str());
// match[1]: 第一个捕获组(括号内的数字)
// .str(): 转换为字符串
// std::stoi(): 将字符串转换为整数并返回
}
catch (...) {
return -1; // 如果转换失败,返回 -1
}
}
那么在这几句代码中,使用match[0]和match[1]有什么区别吗?
match[0]:存储完整匹配的内容(整个正则表达式匹配到的字符串)
match[1]:存储第一个捕获组的内容(第一对括号 () 内匹配的内容)
之前的代码中因为只设置了一个捕获组,所以match[0]和match[1]相同。
当正则表达式更复杂时
示例 1:带前缀的匹配
std::string filename = "file_123.txt";
std::regex pattern(R"(file_(\d+))"); // 注意:只有数字部分有括号
std::smatch match;
if (std::regex_search(filename, match, pattern)) {
std::cout << "match[0]: " << match[0] << "\n"; // "file_123"
std::cout << "match[1]: " << match[1] << "\n"; // "123"
}
示例 2:多个捕获组
std::string filename = "report_2024_10_21.pdf";
std::regex pattern(R"((\d{4})_(\d{2})_(\d{2}))");
std::smatch match;
if (std::regex_search(filename, match, pattern)) {
std::cout << "match[0]: " << match[0] << "\n"; // "2024_10_21"
std::cout << "match[1]: " << match[1] << "\n"; // "2024"
std::cout << "match[2]: " << match[2] << "\n"; // "10"
std::cout << "match[3]: " << match[3] << "\n"; // "21"
}
示例 3:非捕获组
std::string filename = "image_001.jpg";
std::regex pattern(R"((?:image_)(\d+))"); // (?:...) 是非捕获组
std::smatch match;
if (std::regex_search(filename, match, pattern)) {
std::cout << "match[0]: " << match[0] << "\n"; // "image_001"
std::cout << "match[1]: " << match[1] << "\n"; // "001"
// 没有 match[2],因为 (?:...) 不算捕获组
}
更多推荐
所有评论(0)