正则表达式(regular expression)的C++库regex是一种强大的描述字符序列的工具 , C++11中也将正则表达式纳入了新标准的一部分 。
regex库中常用组件介绍
在头文件中包含了多个我们使用正则表达式时需要用到的组件,即 #include
regex库组件详细介绍如下
regex | 表示有一个正则表达式类,比如:regex pattern(“(.{3})(.{2})_(\d{4})!”) |
regex_match | 全文匹配,要求整个字符串符合正则表达式的匹配规则。用来判断一个字符串和一个正则表达式是否模式匹配,返回一个 bool 值,true 为匹配,false 为不匹配。匹配的含义是目标字符串必须完全和正则表达式相匹配,不能有多余的字符,如果需要部分匹配则应使用regex_search |
regex_search | 搜索匹配,根据正则表达式来搜索字符串中是否存在符合规则的子字符串。 能和正则表达式相匹配就返回true |
regex_replace | 替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。要求输入一个正则表达式,以及一个用于替换匹配子字符串的格式化字符串。这个格式化字符串可以通过转义序列引用匹配子字符串中的部分内容 |
sregex_iterator | 迭代器适配器,调用regex_search来遍历一个string中所有匹配的子串 |
smatch/match_results | 容器类,保存在string中搜索的结果。如果匹配成功,这些函数将成功匹配的相关信息保存在给定的smatch对象中。比如:smatch results;将匹配结果存放在results中,另一种存储方法声明:match_results |
基本概念:
match是全文匹配,即要求整个字符串符合匹配规则。
//头文件包含
#include
#include
using namespace std;
int main()
{
cout << regex_match("123", regex("\\d")) << endl; //结果为0
cout << regex_match("123", regex("\\d+")) << endl; //结果为1
return 0;
}
编译及运行:
Program returned: 0
Program stdout
0
1
上述方法返回值为bool值,主要用于if条件表达式中。
匹配结果
更多的时候我们希望能够获得匹配结果(字符串),对结果进行操作。这时就需要对匹配结果进行存储,共有两种存储方式。
match_results<string::const_iterator> result;
smatch result; //推荐
第二种方式使用起来更简洁、方便,推荐使用
eg:
//头文件包含
#include
#include
using namespace std;
int main()
{
string str = "Hello_2018";
smatch result;
regex pattern("(.{5})_(\\d{4})"); //匹配5个任意单字符 + 下划线 + 4个数字
if (regex_match(str, result, pattern))
{
cout << result[0] << endl; //完整匹配结果,Hello_2018
cout << result[1] << endl; //第一组匹配的数据,Hello
cout << result[2] << endl; //第二组匹配的数据,2018
cout<<"结果显示形式2"<<endl;
cout<< result.str() << endl; //完整结果,Hello_2018
cout<< result.str(1) << endl; //第一组匹配的数据,Hello
cout << result.str(2) << endl; //第二组匹配的数据,2018
//遍历结果
for (int i = 0; i < result.size(); ++i)
{
cout << result[i] << endl;
}
}
}
编译并运行:
rogram returned: 0
Program stdout
Hello_2018
Hello
2018
结果显示形式2
Hello_2018
Hello
2018
// 头文件包含
#include
#include
using namespace std;
int main() {
// 匹配结果存放声明
smatch results; // match_results
// results;是第二种存储方法
// 匹配字符串和正则pattern准备
string str = "2019年12月看的电视hhhhh大亨堡是不是小七的最好吃。你信不信啊?";
string pattern("(会不会|是不是|能不能|信不信)");
regex r(pattern); // regex 表示一个正则表达式类
cout << regex_match(str, results, r) << endl; // 输出结果为:0
if (regex_match(str, results, r)) {
cout << results[0] << endl;
}
}
编译及运行
Executor x86-64 gcc 9.5 (C++, Editor #1)
x86-64 gcc 9.5
x86-64 gcc 9.5
Compiler options...
Program returned: 0
Program stdout
0
基本概念:
search是搜索匹配,即搜索字符串中存在符合规则的子字符串。
match与search一比较便知:
//头文件包含
#include
#include
using namespace std;
int main()
{
cout << regex_match("123", regex("\\d")) << endl; //结果为0
cout << regex_search("123", regex("\\d")) << endl; //结果为1
}
编译并运行
rogram returned: 0
Program stdout
0
1
eg:
// 头文件包含
#include
#include
using namespace std;
int main() {
string str = "Hello 2018, Bye 2017";
smatch result;
regex pattern("\\d{4}"); // 匹配四个数字
// 迭代器声明
string::const_iterator iterStart = str.begin();
string::const_iterator iterEnd = str.end();
string temp;
while (regex_search(iterStart, iterEnd, result, pattern)) {
temp = result[0];
cout << temp << " ";
iterStart = result[0].second; // 更新搜索起始位置,搜索剩下的字符串
}
std::cout<<"AAAA"<<std::endl;
regex_search(str, result, pattern);
std::cout<<result[0]<<std::endl;
std::cout<<result[1]<<std::endl;
}
编译并运行:
Program returned: 0
Program stdout
2018 2017 AAAA
2018
基本概念
replace是替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。
// 头文件包含
#include
#include
using namespace std;
int main() {
string str = "Hello_2018!";
regex pattern("Hello");
cout << regex_replace(str, pattern, "")
<< endl; // 输出:_2018,将Hello替换为""
cout << regex_replace(str, pattern, "Hi")
<< endl; // 输出:Hi_2018,将Hello替换为Hi
}
编译及运行
Program returned: 0
Program stdout
_2018!
Hi_2018!
除了直接替换以外,还有可以用来调整字符串内容(缩短、顺序等)。
// 头文件包含
#include
#include
using namespace std;
int main() {
string str = "Hello_2018!";
regex pattern2(
"(.{3})(.{2})_(\\d{4})"); // 匹配3个任意字符+2个任意字符+下划线+4个数字
cout
<< regex_replace(str, pattern2, "$1XX$3")
<< endl; // 输出:Hel2018,将字符串替换为第一个和第三个表达式匹配的内容
cout << regex_replace(str, pattern2, "$1$3$2")
<< endl; // 输出:Hel2018lo,交换位置顺序
}
编译及运行
Executor x86-64 gcc 9.5 (C++, Editor #1)
x86-64 gcc 9.5
x86-64 gcc 9.5
Compiler options...
Program returned: 0
Program stdout
HelXX2018!
Hel2018lo!
匹配的时候忽略大小写,这时候就要用到Regex的语法选项了。
regex::icase:匹配时忽略大小写。
// 头文件包含
#include
#include
using namespace std;
int main() {
cout << regex_match("aaaAAA", regex("a*", regex::icase)) << endl; // 结果为1
cout << regex_match("aaaAAA", regex("a*")) << endl; // 结果为0
}
编译及运行
Executor x86-64 gcc 9.5 (C++, Editor #1)
x86-64 gcc 9.5
x86-64 gcc 9.5
Compiler options...
Program returned: 0
Program stdout
1
0
六、正则表达式部分语法
\ 表示将下一字符标记为特殊字符、转义字符;C++中要注意转义字符,比如:“\\d+”;
^ 表示字符串的开始,匹配输入字符串开始的位置;
$ 表示字符串的结尾,匹配输入字符串结尾的位置;
. 表示匹配除换行符" \n "以外的任意字符;
\w 表示任意字母、数字、下划线 ;
\s 表示任意空白符(tab也包含在内);
\d 表示匹配单个数字字符,\D 表示非数字字符匹配;
[] 表示一个字符集合,匹配指定范围内的任何字符,例如[a-z]表示字母a~z所组成的集合;
[]中使用^来表示集合的补集,匹配不在指定的范围内的任何字符,例如1-3表示除1 2 3以外数字;
[[:alpha:]] 表示任何字母;
[[:alnum:]] 表示任何字母和数字;
regex::icase 表示匹配时忽略大小写;
{n} 表示正好匹配 n 次前面的字符或表达式,例如"hello{6}",匹配字符串中符合第二个l后边有6个o的子字符串;
{n, } 表示至少匹配 n 次前面的字符或表达式;
{n,m} 表示匹配至少 n 次,至多 m 次前面的字符或表达式;
? 表示零次或一次匹配前面的字符或子表达式;
\t \n \r这些平时非常常见,分别表示制表符匹配、换行符匹配、回车符匹配