转义字符
在讲具体方法之前,我们先了解下C++中使用正则表达式需要注意的一个问题:转义字符
cout << regex_match("123", regex("\d+")) << endl; //结果为0,需要转义字符'\'
cout << regex_match("123", regex("\\d+")) << endl; //结果为1,完全匹配
- \d:匹配一个数字字符;
- + :匹配一次或多次;
2、regex_match
2.1、基本概念
match是全文匹配,即要求整个字符串符合匹配规则。
cout << regex_match("123", regex("\\d")) << endl; //结果为0
cout << regex_match("123", regex("\\d+")) << endl; //结果为1
上述方法返回值为bool值,主要用于if条件表达式中。
2.2、匹配结果
更多的时候我们希望能够获得匹配结果(字符串),对结果进行操作。这时就需要对匹配结果进行存储,共有两种存储方式。
match_results<string::const_iterator> result;
smatch result; //推荐
第二种方式使用起来更简洁、方便,推荐使用。
2.3 实例
下面看一个match方法匹配的实例,看看实际应用:
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;
}
result[]与result.str()这两种方式能够获得相同的值,我更喜欢用数组形式的。
在匹配规则中,以括号()的方式来划分组别,实例中的规则共有两个括号,所以共有两组数据。
1.匹配算法( 使用函数regex e()与regex_match() )
第一种
#include<iostream>
#include<string>
using namespace std;
//添加头文件
#include <regex>
//写一个匹配函数
bool IsEmail(string Str)
{
regex e("\\d+\\.\\d+\\.\\d+\\.\\d"); //IP地址匹配大概、
//regex e("[a-g]"); //区间匹配
//regex e("[a-g]*"); //*号与区间匹配联合使用
//regex e("(\\w){4,10}"); //表示4-10个字符 指定个数
//regex e("ada(e|b)"); //表示或者
//regex e("^[a-z]"); //属于a-a [^a-z] 不属于a-z
//regex e("[a-zA-Z][a-zA-Z0-9_]{4,15}");
bool b = regex_match(Str, e);
return b;
}
int main(){
//一个string 类
string str;
cin >> str;
if (IsEmail(str)){ //根据是否匹配返回对应的输出,当然实际应用中不仅仅如此。
cout << "This is an email" << endl;
}
else cout << "This is not an email" << endl;
return 0;
}
第二种
int main(){
regex e("w*");
string str;
cin >> str;
if (regex_match(str, e)){
cout << "true" << endl;
}
else{
cout << "false" << endl;
}
}
如图可知表示一个或多个字母或者数字
3 regex_search
3.1 基本概念
search是搜索匹配,即搜索字符串中存在符合规则的子字符串。
match与search一比较便知:
cout << regex_match("123", regex("\\d")) << endl; //结果为0
cout << regex_search("123", regex("\\d")) << endl; //结果为1
3.2 实例
直接看例子:
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; //更新搜索起始位置,搜索剩下的字符串
}
输出结果:2018 2017
只需要利用迭代器就可以很轻松的访问到所有匹配的结果值。
4 regex_replace
4.1 基本概念
replace是替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。
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
4.2 扩展
除了直接替换以外,还有可以用来调整字符串内容(缩短、顺序等)。
string str = "Hello_2018!";
regex pattern2("(.{3})(.{2})_(\\d{4})"); //匹配3个任意字符+2个任意字符+下划线+4个数字
cout << regex_replace(str, pattern2, "$1$3") << endl; //输出:Hel2018,将字符串替换为第一个和第三个表达式匹配的内容
cout << regex_replace(str, pattern2, "$1$3$2") << endl; //输出:Hel2018lo,交换位置顺序
$n用于表示第n组匹配数据,所以我们可以利用这种方式来将字符串的内容进行调整。
5 匹配忽略大小写
有时我们希望能够匹配的时候忽略大小写,这时候就要用到Regex的语法选项了。
cout << regex_match("aaaAAA", regex("a*", regex::icase)) << endl; //结果为1
cout << regex_match("aaaAAA", regex("a*")) << endl; //结果为0
regex::icase:匹配时忽略大小写。
6 帮助网站
附上两个写正则表达式常用到的网站
2. 搜索算法( 使用函数regex e() 与 regex_search() )
#include<iostream>
using namespace std;
#include <regex>
int main(){
string str("First of of the world."); //在此处可以存放任何想搜索的字符串,当然
//当然,字符串的赋值还可以 string str = {" First of of the world." };
regex e("\\b(o)[^ ?.]+"); // ^ 在字符集里面表示的是一个否定
smatch m; //存放string 类型的结果 string类型的迭代器
while (regex_search(str, m, e)){
cout << m.str() << " "; //打印出该单词
str = m.suffix().str(); //迭代器的方法,往后面去匹配,如果去掉会形成死循环
}
return 0;
}