C++正则分组

前言

输入的源码当做是字符串,我需要把其中的标识符、数字、复数、函数、关键字等识别出来。之前做的计算器改进版本时,用了两次匹配,第一次分割Token,第二次分类Token,但是我想让这个分类步骤快一点,如果能在第一次分割的时候得到分组信息也就能省略第二次匹配了!


$n,n>0

regex_replace也能得到分组,但是其返回的是相同分组的结果的结合,返回的只有一个字符串。我也想过对这个字符串进行分割,如果再用正则就违反我的要求了!所以我试过用空格来进行分割,但是这个字符串有些结果间是空格,有些没有。

string result = regex_replace(str,reg,"$1");//返回匹配reg的第一个分组的内容

匹配结果

匹配结果放在smatch类里,迭代器的内容就是smatch类。
smatch 类的 size() 指的是分组个数,也就是正则中左括号的个数。
.str(n) 表示第n个分组的内容。n=0时表示总的匹配结果,不传入参数也是一样。


	regex reg1("([a-zA-Z\\_]\\w*)|(,)|([\\+\\-\\*\\/\\^\\%\\(\\)])|(\\d+(\\.\\d+)?(e[\\+\\-]?\\d+)?)");
	string str1 = "43+12 - Print(3,4)*7";
	for (sregex_iterator it(str1.begin(), str1.end(), reg1), it_end; it != it_end; ++it) {
    
    
		for (int i = 0; i < 8; ++i) {
    
    
			cout << i << ">" << (*it).str(i) << "\t";			
		}
		cout << endl;	
	}

	

运行结果

0>43    1>      2>      3>      4>43    5>      6>      7>
0>+     1>      2>      3>+     4>      5>      6>      7>
0>12    1>      2>      3>      4>12    5>      6>      7>
0>-     1>      2>      3>-     4>      5>      6>      7>
0>Print 1>Print 2>      3>      4>      5>      6>      7>
0>(     1>      2>      3>(     4>      5>      6>      7>
0>3     1>      2>      3>      4>3     5>      6>      7>
0>,     1>      2>,     3>      4>      5>      6>      7>
0>4     1>      2>      3>      4>4     5>      6>      7>
0>)     1>      2>      3>)     4>      5>      6>      7>
0>*     1>      2>      3>*     4>      5>      6>      7>
0>7     1>      2>      3>      4>7     5>      6>      7>
请按任意键继续. . .

从上面明显看出,不同的种类的子字符串的最大非空值的索引可以区分它们的种类!

我们只需要记录这个索引就行了,再根据正则的分组来分类不同的子字符串。

	for (sregex_iterator it(str1.begin(), str1.end(), reg1), it_end; it != it_end; ++it) {
    
    
		//cout << it->str() << ",len=" << it->length() <<","<< endl;
		
		bool flag = false;
		int j = 0, k = 0;
		//cout << "size="<<(*it).size() << endl;
		for (int i = 0; i < 7; ++i) {
    
    
			if (i != 0) {
    
    
				if ((*it).str(i) != "") {
    
    
					flag = true;  //当遇到非空的后,就不再计算空的个数
					++k;
				}
				else {
    
    
					if (!flag)	++j;
				}
			}
			cout << i << ">" << (*it).str(i) << "\t";			
		}
		cout << "\tindex=" << j + k << endl;
		
	}
  • 本来凌晨想写这篇说明C++里做正则分类还是搞二次匹配吧!因为一次匹配再搞方法得到分组信息的速度太慢,当时想的方法是给不同分组加上逐迹递增的括号这样的方法2333。早上把文章写了一半后晚上又测试了一下,发现其实不加多余的括号分组信息也显示出来了,而且正则的括号越多性能越低,大家要尽量少写括号!
  • 同样为了性能,中括号中的\\+号也不要\\了,还有减号,点,问号,小括号,花括号,星号等在放入中括号后,都用原来的符号就行,不要加两个转义符。

猜你喜欢

转载自blog.csdn.net/weixin_41374099/article/details/104106090