c++11 正则表达式 std::regex写法与异常处理
时间:2026-08-10 | 作者:冻月看渠 | 阅读:0C++11正则表达式是标准库提供的文本匹配能力,核心类型是std::regex,常配合std::regex_match、std::regex_search、std::sregex_iterator和std::regex_replace使用。它适合处理格式校验、字段提取、批量替换等常见任务;只要把匹配、分组、转义和异常处理几部分理顺,就能较稳定地落地到实际代码中。
基本类型与语法
使用C++11正则表达式需要包含regex头文件,编译时至少启用C++11标准,例如g++ -std=c++11 main.cpp。std::regex负责保存编译后的表达式,std::smatch用于接收针对std::string的匹配结果,std::cmatch则适用于字符数组。默认语法是std::regex_constants::ECMAScript;如果需要,还可以在构造时传入std::regex_constants::basic、extended等语法模式,或叠加std::regex_constants::icase实现大小写不敏感匹配。例如std::regex re("hello", std::regex_constants::icase);可以同时匹配Hello、HELLO和hello。转义时要区分C++字符串和正则语法两层含义:普通字符串里的d+表示把d+交给正则引擎,而原始字符串R"(d+)"会保留反斜杠本意,更适合书写复杂表达式。若要匹配文本中的单个反斜杠,普通字符串常写成\,原始字符串可写成R"()",可读性差异会非常明显。
- std::regex:创建和保存正则表达式
- std::smatch:保存std::string的匹配结果
- std::regex_error:表示表达式编译或执行错误
- 默认语法为ECMAScript,可在构造时切换basic、extended等模式
- 可通过std::regex_constants::icase设置大小写不敏感匹配
完整匹配与局部查找
std::regex_match要求整个目标字符串都符合表达式,适合校验邮箱、日期或编号等完整格式;std::regex_search只需在字符串中找到一个符合条件的片段,更适合日志检索和字段提取。下面是一个可直接编译的最小示例,分别演示完整匹配、局部查找和捕获分组读取:
#include
#include
#include
int main() {
std::string code = "AB-1024";
std::regex full_re(R"([A-Z]{2}-d{4})");
if (std::regex_match(code, full_re)) {
std::cout << "match whole string" << std::endl;
}
std::string text = "订单号: AB-1024, 状态: done";
std::smatch match;
std::regex search_re(R"(([A-Z]{2})-(d{4}))");
if (std::regex_search(text, match, search_re)) {
std::cout << match.str(0) << std::endl; // AB-1024
std::cout << match.str(1) << std::endl; // AB-1024
std::cout << match.str(2) << std::endl; // AB
std::cout << match.str(3) << std::endl; // 1024
}
} 运行后可看到regex_match用于整串校验,regex_search用于提取首个命中片段。match.str(0)表示完整命中内容,match.str(1)、match.str(2)等依次对应各捕获组;如果使用match[0]、match[1]也能读取相同结果。
- std::
regex_match用于验证整个字符串 - std::
regex_search用于查找第一个匹配片段 - match.
str(0)读取完整结果,match.str(1)起读取各捕获分组 - match[0]、match[1]与match.
str(0)、match.str(1)是常见等价写法
遍历与替换
需要查找全部匹配项时,可以使用std::sregex_iterator遍历目标字符串,每次取得一个匹配结果。需要修改文本时,可调用std::regex_replace,将所有符合表达式的内容替换为指定字符串。下面的示例同时演示全部遍历、分组读取和在替换模板中使用$1、$2重排内容:
#include
#include
#include
int main() {
std::string text = "2026-08-05 2026-09-01";
std::regex date_re(R"((d{4})-(d{2})-(d{2}))");
for (std::sregex_iterator it(text.begin(), text.end(), date_re), end; it != end; ++it) {
const std::smatch& m = *it;
std::cout << m.str(0) << " -> year=" << m.str(1)
<< ", month=" << m.str(2)
<< ", day=" << m.str(3) << std::endl;
}
std::string replaced = std::regex_replace(text, date_re, "$3/$2/$1");
std::cout << replaced << std::endl; // 05/08/2026 01/09/2026
} 这里m.str(0)是完整日期,m.str(1)、m.str(2)、m.str(3)分别是年、月、日。regex_replace里的$1、$2、$3表示引用捕获分组,因此非常适合日期格式重排、字段脱敏和模板化替换。处理大文本前仍应评估表达式复杂度,避免过度回溯造成明显的运行时间增长。
- std::
sregex_iterator用于遍历全部匹配项 - 可在循环中通过m.
str(0)、m.str(1)等读取每次命中的完整结果和分组 - std::
regex_replace用于批量替换匹配内容 - 替换字符串中的$1、$2、$3可直接引用对应捕获分组
错误处理与使用建议
构造std::regex时,如果表达式语法无效,标准库会抛出std::regex_error,因此动态表达式应放在异常处理代码中。下面是一个最小排错示例:
#include
#include
#include
int main() {
std::string pattern = "([A-Z]+";
try {
std::regex re(pattern);
} catch (const std::regex_error& e) {
std::cout << "regex error: " << e.what() << std::endl;
std::cout << "error code: " << static_cast(e.code()) << std::endl;
}
} 这个例子中的左括号没有闭合,构造阶段就会失败,因此需要在创建regex对象时立即捕获异常。e.what()可读取错误描述,e.code()可区分错误类别;如果表达式来自配置文件、用户输入或数据库,而不是写死在源码中,更应该在构造阶段处理失败路径。正则表达式适合结构清晰的文本规则,但不宜承担完整语法解析任务。对于固定前缀、单字符查找或简单分隔,普通字符串函数通常更直观,也可能具有更稳定的性能。实际使用时还应准备空字符串、边界长度、非法字符和未匹配分组等测试用例。
- 捕获const std::regex_error&并读取
what()与code() - 动态表达式要在构造std::regex时处理失败
- 优先选择清晰且回溯较少的表达式
- 为边界输入和失败路径编写测试
掌握语法选项、匹配方式、分组读取、遍历替换和异常处理后,C++11正则表达式就能覆盖大多数常见文本任务。实际落地时应明确是否需要整串校验、首个命中还是全部命中,同时注意转义层次和构造阶段报错,这样代码会更容易维护和排查。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- vc 正则表达式 std::regex与Boost.Regex选择
- 时间:2026-08-10
-
- c++ 正则表达 regex匹配提取替换示例
- 时间:2026-08-10
-
- 正则表达式c语言
- 时间:2026-08-10
-
- c正则表达式语法大全 POSIX语法量词分组速查
- 时间:2026-08-10
-
- c正则表达式 regex.h语法函数与完整代码
- 时间:2026-08-10
-
- c 正则表达式 regex.h匹配提取示例
- 时间:2026-08-10
精选合集
更多大家都在玩
大家都在看
更多-
- 糖尿病完全不能吃糖吗
- 时间:2026-09-15
-
- 蚂蚁庄园小课堂2026年9月16日最新题目答案
- 时间:2026-09-15
-
- 小鸡答题今天的答案是什么2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园每日答题答案2026年9月16日
- 时间:2026-09-15
-
- 以下哪种粮食是酿造绍兴黄酒的主要原料 蚂蚁庄园今日答案9月16日
- 时间:2026-09-15
-
- 劝学名句“及时当勉励,岁月不待人”出自哪位诗人 蚂蚁庄园今日答案9.16
- 时间:2026-09-15
-
- 蚂蚁庄园今天答题答案2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园答题今日答案2026年9月16日
- 时间:2026-09-15