从C++11开始,C++ 通过标准库提供正则表达式支持。在使用时需要包含头文件
regex:表示有一个用于匹配的正则表达式的类。
smatch:容器类,以string格式保存搜索的结果。S表示string。
regex_search: 寻找第一个与正则表达式匹配的子序列。
void test01()
{
string pattern("[^c]ei");
string pattern1 = "[[:alpha:]]*" + pattern + "[[:alpha:]]*";
// pattern 和 pattern1 都是在定义字符串,字符串的表示的是内容是正则表达式
// 此时还只是字符串,并不是真正的Cpp可以识别的正则表达式或者说规则
regex r(pattern1); // 构造一个用于查找的regex类
// regex类的实例化r才是真正的正则表达式,才是搜索规则
smatch results; // 定义一个保存搜索结果的对象
string test_str = "receipt friend theif receive"; //带搜索的字符串
// 用 r 在 test_str 中查找与 pattern 匹配的字符串
if(regex_search(test_str,results,r)) // 匹配字符串
// 从头开始找到第一个匹配子字符串的,返回true,保存结果到results,然后退出
cout << results.str() << endl; // 打拼匹配的字符串
}
如果将上述test01中的内容做如下修改,那么就是错误的。
regex_search(“receipt friend theif receive”, results, r);
因为存放结果的是smatch
对象的实例化results
,smatch
对应的是string
,而 “receipt friend theif receive” 是C风格的char *。这是不匹配的,第一个处理方法就是将其转换成string类型,如上代码所示,第二个解决方法就是将smatch改为cmatch。
(C++中的string是一个容器类。)
指定一些标志来影响regex的搜索结果。
比如regex::icase
选项表示的是在匹配中忽略大小写。如果没有该选项,就只会匹配小写字母。
regex r(“[[:alnum:]]+\\.(cpp|cxx|cc)$”,regex::icase);
对于正则表达式本身的解析:
[[:alnum:]]
表示的是任意一个字母或者数字
\\.
表示一个点,因为 . 本身在正则表达式中有特殊意义,所以需要一个转义符 \ ,而 \ 在cpp中也有特殊意义,所以还需要一个转义。
$
表示以该表达式为结尾的字符串
前面用smatch
去存放regex_search
匹配结果的时候只是得到了匹配到的第一个结果,如果想要看到其他匹配到的其他结果,就要使用迭代器sregex_iterator
。测试案例如下:
void test02()
{
string test_str = "Hello cei world freind meizu";
string pattern("[^c]ei");
string pattern1 = "[[:alpha:]]*" + pattern + "[[:alpha:]]*";
regex r(pattern1,regex::icase);
for(sregex_iterator it(test_str.begin(),test_str.end(),r),end_it;it!=end_it; ++it)
cout << it->str() <<" ";
cout << endl;
}
it
,一个end_it
;sregex_iterator it(test_str.begin(),test_str.end(),r)
将it
初始化为第一个匹配位置除了显示匹配内容本身,还可以访问到匹配文本前后的内容,具体如下:
void test02()
{
string test_str = "Hello cei world freind adcdef meizu fghijk";
string pattern("[^c]ei");
string pattern1 = "[[:alpha:]]*" + pattern + "[[:alpha:]]*";
regex r(pattern1, regex::icase);
// 显示上下文
for (sregex_iterator it(test_str.begin(), test_str.end(), r), end_it; it != end_it; ++it)
{
auto pos = it->prefix().length();
pos = pos > 5 ? pos - 5 : 0;
cout <<"---" << it->prefix().str().substr(pos)<< "---"
<< "\t>>>" << it->str() << "<<<\t"
<<"---"<< it->suffix().str().substr(0, 5) << "---" << endl<<endl;
}
}
将正则表达式的内容用 ( ) 括起来就是一组,然后每一组的内容可以单独显示。示例如下:
// 分组/子匹配
void test03()
{
string test_str("test01.cpp test02.hpp");
string pattern = "[[:alpha:]]+((\\d+)\\.(cpp|hpp|cc))";
regex r(pattern);
smatch results;
if (regex_search(test_str, results, r))
{
for (int i = 0; i < results.size(); i++)
{
cout << results.str(i) << endl;
}
cout << "============" << endl;
for (int i = 0; i < results.size(); i++)
{
cout << results[i].str() << endl;
}
}
cout << "============" << endl;
for (sregex_iterator it(test_str.begin(), test_str.end(), r), end_it; it != end_it; ++it)
{
for (int i = 0; i < it->str().size(); i++)
{
cout << it->str(i) << " ";
}
cout << endl;
}
cout << endl;
}
(A)(B(C))
中存在如下四个组:分组编号 | 对应的自表达式 |
---|---|
0 | (A)(B(C)) |
1 | (A) |
2 | (B(C)) |
3 | (C) |