c++ 正则表达 regex匹配提取替换示例
时间:2026-08-10 | 作者:夜鞌不睡 | 阅读:0在C++中,正则表达式常用于文本查找、格式校验、内容提取和批量替换。本文围绕标准库regex组件,补充字符类、锚点、量词、分组与转义等常用语法,结合可直接编译运行的完整示例说明匹配、提取、遍历、替换和异常处理的实际用法。
正则表达式的基本用法
C++标准库在regex头文件中提供正则表达式支持。使用时先创建std::regex对象,再根据任务选择完整匹配、局部搜索或内容替换。默认语法接近ECMAScript,普通字符表示自身,点号匹配除换行符外的单个字符,星号表示前一项出现零次或多次,加号表示出现一次或多次,问号表示出现零次或一次。除了这些基础量词,实际开发中还常用字符类如[abc]、范围如[A-Z]、数字类d、空白类s、锚点^和$、数量词{m,n}、圆括号捕获组、竖线选择符a|b等语法。若需要跨行匹配任意字符,不能只依赖点号,通常应明确写成[sS]这类模式。书写规则时还要区分普通字符串和原始字符串:普通字符串中的d要写成"d",原始字符串R"(d)"则更直观。
- std::regex_match用于判断整个字符串是否符合规则。
- std::regex_search用于查找字符串中是否存在符合规则的片段。
- std::regex_replace用于将所有符合规则的内容替换为指定文本。
匹配与格式校验
格式校验通常要求输入内容从头到尾都符合规则,因此适合使用std::regex_match。编写模式时应明确字符范围和长度,避免使用过于宽泛的通配规则。例如校验由字母开头、后接字母或数字的标识符,可以使用原始字符串保存模式,减少反斜杠转义带来的阅读负担。规则[A-Za-z][A-Za-z0-9]{2,15}表示首字符必须是字母,后面再跟2到15个字母或数字,因此总长度实际是3到16个字符。若目标长度不是3到16位,就要同步调整{2,15}这一段。下面是一个可直接编译运行的最小完整示例。
- std::regex rule(R"([A-Za-z][A-Za-z0-9]{2,15})");
- bool valid = std::regex_match(input, rule);
- 原始字符串R"()"可以让反斜杠等正则字符保持直观。
示例程序:
#include#include #include int main() { std::regex rule(R"([A-Za-z][A-Za-z0-9]{2,15})"); std::string ok = "Code88"; std::string shortName = "A1"; std::string badStart = "9Code"; std::cout << ok << " -> " << std::regex_match(ok, rule) << 'n'; std::cout << shortName << " -> " << std::regex_match(shortName, rule) << 'n'; std::cout << badStart << " -> " << std::regex_match(badStart, rule) << 'n'; } 输出结果:Code88 -> 1;A1 -> 0;9Code -> 0。
搜索与分组提取
需要从一段文本中提取部分内容时,可配合std::smatch和std::regex_search使用。匹配成功后,下标零保存完整结果,后续下标依次对应圆括号定义的捕获组。访问分组前应先确认匹配成功,并检查分组数量,避免读取不存在的结果。下面的日期提取程序包含头文件、输入文本、调用方式和输出结果,便于直接验证。
- std::regex rule(R"((d{4})-(d{2})-(d{2}))");
- std::smatch result;
- 匹配成功后,result[1]、result[2]和result[3]分别保存年、月、日。
示例程序:
#include#include #include int main() { std::string text = "today is 2026-08-05."; std::regex rule(R"((d{4})-(d{2})-(d{2}))"); std::smatch result; if (std::regex_search(text, result, rule) && result.size() >= 4) { std::cout << "full: " << result[0].str() << 'n'; std::cout << "year: " << result[1].str() << 'n'; std::cout << "month: " << result[2].str() << 'n'; std::cout << "day: " << result[3].str() << 'n'; } } 输出结果:full: 2026-08-05;year: 2026;month: 08;day: 05。
遍历全部匹配结果
std::regex_search通常只返回当前搜索范围内的第一个结果。若要提取文本中的全部匹配项,可以使用std::sregex_iterator遍历,也可以在每次匹配后从剩余文本继续搜索。迭代器方式结构更清晰,适合日志分析、编号提取和批量数据清洗。下面用完整程序演示如何遍历文本中的全部数字编号。
- std::sregex_iterator begin(text.begin(), text.end(), rule);
- std::sregex_iterator end;
- 从begin遍历到end即可依次读取每个匹配结果。
示例程序:
#include#include #include int main() { std::string text = "item12 item34 item567"; std::regex rule(R"(d+)"); std::sregex_iterator begin(text.begin(), text.end(), rule); std::sregex_iterator end; for (std::sregex_iterator it = begin; it != end; ++it) { std::cout << it->str() << 'n'; } } 输出结果依次为:12、34、567。
替换文本内容
std::regex_replace可以完成批量替换,并允许在替换模板中引用捕获组。例如调整日期字段顺序时,可以先捕获年、月、日,再在替换文本中重新排列。处理用户输入的替换内容时,需要留意其中是否包含具有特殊含义的引用符号。若只是做固定格式转换,先写出最小完整示例再扩展更稳妥。
- 日期替换可以复用前文定义的年、月、日捕获规则。
- std::string output = std::regex_replace(text, rule, "$3/$2/$1");
- 替换模板中的$1、$2和$3对应前三个捕获组。
示例程序:
#include#include #include int main() { std::string text = "截止日期: 2026-08-05"; std::regex rule(R"((d{4})-(d{2})-(d{2}))"); std::string output = std::regex_replace(text, rule, "$3/$2/$1"); std::cout << output << 'n'; } 输出结果:截止日期: 05/08/2026。
性能与异常处理
正则模式构造可能消耗一定资源,重复使用同一规则时,应尽量复用已经创建的std::regex对象。复杂模式还可能导致匹配效率下降,因此应限制不必要的通配和回溯。模式语法错误会抛出std::regex_error,规则来自配置或外部输入时,不能只停留在原则说明,还应明确展示try/catch、错误记录和降级策略。常见做法是捕获const std::regex_error&,同时输出what()和code(),再返回失败状态或改用更保守的默认规则。
- 将固定规则定义为可复用对象,避免在循环中反复构造。
- 优先使用明确的字符范围和长度,减少模糊匹配。
- 捕获std::regex_error后,可通过code方法判断错误类型。
示例程序:
#include#include #include bool build_rule(const std::string& pattern, std::regex& outRule) { try { outRule = std::regex(pattern); return true; } catch (const std::regex_error& e) { std::cerr << "regex error: " << e.what() << 'n'; std::cerr << "error code: " << static_cast (e.code()) << 'n'; return false; } } int main() { std::regex rule; std::string badPattern = "([A-Z]+"; if (!build_rule(badPattern, rule)) { std::cout << "fallback: skip current rule or switch to a safe default pattern." << 'n'; } } 该示例用于说明:当规则来自配置文件、数据库或用户输入时,构造失败后应返回false、中止当前匹配,或切换到预置的安全规则,而不是继续使用无效模式。
掌握匹配、搜索、提取和替换这四类操作后,便能处理多数C++文本任务。实际使用时应优先保证规则清晰可读,先用最小完整程序验证输入、输出和边界,再通过空字符串、超长文本、非法规则等异常数据检查结果是否符合预期。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- c++11 正则表达式 std::regex写法与异常处理
- 时间:2026-08-10
-
- vc 正则表达式 std::regex与Boost.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