【C++正则表达式】正则表达式基础

正则表达式基础

  • 正则表达式基础语法
  • C++中的正则表达式
    • 基本使用
    • 匹配问题
    • Regex对象的选项
    • 使用迭代器获得所有匹配结果
    • 显示匹配单词出现的上下文
    • 子匹配/分组

正则表达式基础语法

  1. 正则表达式30分钟入门教程
  2. 正则表达式教程

C++中的正则表达式

基本使用

从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对象的实例化resultssmatch对应的是string,而 “receipt friend theif receive” 是C风格的char *。这是不匹配的,第一个处理方法就是将其转换成string类型,如上代码所示,第二个解决方法就是将smatch改为cmatch。
(C++中的string是一个容器类。)

Regex对象的选项

指定一些标志来影响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;
}

运行结果如下:
【C++正则表达式】正则表达式基础_第1张图片

  1. 这里是创建了两个迭代器,一个是it,一个end_it;
  2. sregex_iterator it(test_str.begin(),test_str.end(),r)it初始化为第一个匹配位置

【C++正则表达式】正则表达式基础_第2张图片

显示匹配单词出现的上下文

除了显示匹配内容本身,还可以访问到匹配文本前后的内容,具体如下:

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;
	}
}

执行结果如下:
【C++正则表达式】正则表达式基础_第3张图片

  1. 可以看出空格也算是一个string字符的。
  2. pos是匹配文本前面的全部字符长度,减去一个5,意思打印匹配到的字符的前5个字符的内容。

子匹配/分组

将正则表达式的内容用 ( ) 括起来就是一组,然后每一组的内容可以单独显示。示例如下:

// 分组/子匹配
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;
}

运行结果如下:
【C++正则表达式】正则表达式基础_第4张图片

  1. 访问方式有两种:results.str(i) 和 results[i].str(),其中i为组号
  2. 编号为 0 的内容是正则表达式的全部内容。其余的编号则是从左到右依次从0开始编号,如果遇到嵌套的情况,则是从最外层开始编号,例如在表达式 (A)(B(C)) 中存在如下四个组:
分组编号 对应的自表达式
0 (A)(B(C))
1 (A)
2 (B(C))
3 (C)

你可能感兴趣的:(C++,正则表达式,c++)