C++正则表达式示例:实践应用
\n\n正则表达式(regex)是一种强大的文本处理工具,能够根据复杂模式搜索、替换和验证字符串。C++从C++11标准开始,通过<regex>库提供了对正则表达式的支持。本文将介绍如何在实际中使用std::regex:从简单的验证到数据提取和文本替换。
本文既适合刚接触C++的初学者,也适合希望巩固知识的有经验的开发者。我们将介绍关键函数:std::regex_match、std::regex_search和std::regex_replace,以及捕获组的使用。
<regex>库的主要组件
\n\n在进入示例之前,我们先了解主要的类和函数:
\n\n- \n
- std::regex — 表示正则表达式(模式)的类。通过模式字符串和可选的语法标志(默认ECMAScript)创建。 \n
- std::smatch — 用于存储搜索结果的容器(适用于
std::string类型)。对应的std::cmatch用于C风格字符串。 \n - std::regex_match — 检查整个字符串是否完全匹配模式。 \n
- std::regex_search — 在字符串的任意位置搜索与模式匹配的子串。 \n
- std::regex_replace — 将所有匹配模式的部分替换为指定字符串(支持反向引用)。 \n
所有函数都接受标志来控制行为(例如,std::regex_constants::icase用于不区分大小写的搜索)。
示例1:检查字符串是否匹配模式(std::regex_match)
\n\n最简单的任务是检查字符串是否符合指定格式。例如,检查字符串是否为有效的电子邮件地址(简化版):
\n\n#include <iostream>\n#include <regex>\n#include <string>\n\nint main() {\n std::string email = "user@example.com";\n // 用于验证电子邮件地址的模式(简化版)\n std::regex pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})");\n\n if (std::regex_match(email, pattern)) {\n std::cout << "电子邮件有效。" << std::endl;\n } else {\n std::cout << "电子邮件无效。" << std::endl;\n }\n\n // 检查无效的电子邮件\n std::string bad_email = "user@.com";\n if (std::regex_match(bad_email, pattern)) {\n std::cout << "电子邮件有效。" << std::endl;\n } else {\n std::cout << "电子邮件无效。" << std::endl;\n }\n\n return 0;\n}\n\n输出:
\n电子邮件有效。\n电子邮件无效。\n\n说明:
\n- \n
- 我们使用原始字符串字面量
R"(...)"以避免转义反斜杠。 \n std::regex_match函数仅在整个字符串完全匹配模式时返回true。 \n - 模式
[a-zA-Z0-9._%+-]+表示“指定字符集中的一个或多个字符”。 \n
示例2:搜索子串并提取数据(std::regex_search)
\n\n通常不仅需要验证,还需要查找所有匹配项并提取字符串的部分内容。为此,可以在循环中使用std::regex_search。在以下示例中,我们将查找文本中所有格式为+7-XXX-XXX-XX-XX的电话号码,并提取运营商代码:
#include <iostream>\n#include <regex>\n#include <string>\n\nint main() {\n std::string text = "联系方式:+7-495-123-45-67 和 +7-916-987-65-43。备用号码:+7-495-111-22-33。";\n // 模式:+7-代码(3位数字)-...(用于代码和其余部分的捕获组)\n std::rege