c++ 正则表达式
正则表达式是一种用于文本搜索和处理的表达式语言,它可以用来检查字符串是否符合特定的规则或者从大量的文本数据中筛选出符合规则的数据。C++11及以上版本提供了标准正则表达式库,使得在C++中匹配和检索字符串变得更加简便和高效。本篇文章将介绍C++中正则表达式的使用方法和示例。
一、使用std::regex
使用C++中的正则表达式需要引用头文件<regex>
。C++标准库中提供了std::regex
类来支持正则表达式的操作。
正则式由一个或多个字符构成,用来描述文本中的模式,比如"apple"
就是一个正则式,代表了文本中的一个具体字符串。正则表达式可以包含特殊字符来构成复杂的匹配规则,比如.
代表任意单个字符,[abcd]
代表匹配字母a、b、c和d中的一个。
下面是一个简单的正则式示例,用于匹配邮箱地址:
std::regex pattern(R"(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)");
其中,R"()"
表示将字符串标记为“Raw String”,使得字符串内的特殊字符能够直接被解释而不需要转义。正则表达式中常用的一些特殊字符有:.
表示任意一个字符;^
表示匹配开头;$
表示匹配结尾;*
表示匹配0到多个字符;+
表示匹配1到多个字符;{n}
表示匹配n个字符;{n, m}
表示匹配n到m个字符。
然后,我们可以使用std::regex_match()
函数来匹配一个字符串是否符合给定的正则式:
bool is_email(const std::string& str) {
std::regex pattern(R"(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)");
std::smatch result;
return std::regex_match(str, result, pattern);
}
if (is_email("abc@example.com")) {
std::cout << "This is a valid email address." << std::endl;
} else {
std::cout << "This is not a valid email address." << std::endl;
}
std::regex_match()
函数会返回一个布尔值,表示给定的字符串是否能够匹配给出的正则式。如果匹配成功,std::smatch
类型的结果会被填充,这个类型的变量可以用来获取匹配的子字符串。
二、匹配字符串
std::regex
类提供了很多函数来支持正则表达式的匹配操作。下面是一些常用的函数:
std::regex_search()
:查找给定字符串中第一个满足正则表达式要求的子串。
std::string str("I love C++!");
std::regex pattern(R"(C\+\+)");
if (std::regex_search(str, pattern)) { // true
std::cout << "Matched!" << std::endl;
}
std::regex_replace()
:将给定的字符串中匹配正则式的子字符串替换为指定字符串。
std::string str("Hello, world!");
std::regex pattern(R"(world)");
std::string replacement("C++");
std::string new_str = std::regex_replace(str, pattern, replacement);
std::cout << new_str << std::endl; // Hello, C++!
std::regex_iterator
:遍历给定字符串中所有匹配正则式的子串。
std::string str("I love C++, but not Java.");
std::regex pattern(R"(\\w+\+\+)");
std::sregex_iterator it(str.begin(), str.end(), pattern);
std::sregex_iterator end;
for (; it != end; ++it) {
std::cout << it->str() << std::endl;
}
上述示例中,我们使用std::sregex_iterator
类型来遍历给定字符串中所有匹配正则式R"(\w+\+\+)"
的子串,即以C++
结尾的单词。
三、正则表达式的标志
C++中的正则表达式支持一些标志来控制匹配的行为和方式。std::regex
构造函数中可以添加一个参数,用来指定标志。
std::regex_constants::icase
:不区分大小写匹配。
std::string str("Hello, World!");
std::regex pattern(R"(world)", std::regex_constants::icase);
if (std::regex_search(str, pattern)) { // true
std::cout << "Matched!" << std::endl;
}
std::regex_constants::ECMAScript
:使用ECMAScript引擎,支持UTF-8编码。
std::string str("中文SEO is important.");
std::regex pattern(R"([\u4e00-\u9fa5]+)", std::regex_constants::ECMAScript);
if (std::regex_search(str, pattern)) { // true
std::cout << "Matched!" << std::endl;
}
std::regex_constants::extended
:使用扩展正则表达式语法。
std::string str("127.0.0.1");
std::regex pattern(R"(^\d{1,3}(\.\d{1,3}){3}$)", std::regex_constants::extended);
if (std::regex_search(str, pattern)) { // true
std::cout << "Matched!" << std::endl;
}
四、正则表达式的异常处理
在使用正则表达式时,可能会遇到一些问题,比如正则式写错了、匹配的字符串格式错误等。为了处理这些异常情况,C++中的正则表达式类提供了各种异常类型来表示不同的错误情况。
std::regex_error
:表示所有正则表达式相关的错误。
try {
std::regex pattern(R"(\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*)");
std::smatch result;
std::regex_match("abc@@example.com", result, pattern);
} catch (const std::regex_error& e) {
std::cout << "Regex error: " << e.what() << std::endl;
}
上述示例中,我们故意将邮箱地址格式弄错,导致正则匹配失败,从而抛出了一个std::regex_error
类型的异常。
std::bad_regex
:表示正则表达式语法错误。
try {
std::regex pattern("(?<=中国)北京");
} catch (const std::bad_regex& e) {
std::cout << "Bad regex: " << e.what() << std::endl;
}
上述示例中,"(?<=中国)北京"
是一个非法的正则表达式,会抛出一个std::bad_regex
类型的异常。
结论
正则表达式是一个强大的文本处理工具,在C++中使用正则表达式能够大大提高文本处理的效率和灵活性。本篇文章介绍了C++中的正则表达式库以及在使用中常见的一些操作,希望能够对读者有所帮助。