正则和c++

一、简介

    





二、四种行为

    1、匹配捕获

                
                (1)匹配函数只有完全匹配整个字符串(或者从给定的位置开始的字符串),才会返回true;
                (2)如果要保存匹配的结果,使用smatch result来保存;result[0]是保存整个匹配结果的,result[i]保存第i个捕获组的匹配结果(即第i个括号中的内容),可以使用result.size()可以查看一共有多少个匹配结果。
                (3)例子
                            
	regex pattern("([a-zA-Z]{5})_(\\d{4})");
	string s = "Rosie_1997";
	smatch result;
	if (regex_match(s, result, pattern))
	{
		cout << "匹配成功" << endl;
		for (int i = 0; i <= result.size(); ++i)
		{
			cout << result[i] << endl;
		}
	}
	else
		cout << "匹配失败" << endl;

	string ss = "19970211_rosie_1997";
	if (regex_match(ss.cbegin() + 9, ss.cend(), result, pattern))//从第10个字符开始匹配
	{
		cout << "匹配成功" << endl;
		for (int i = 0; i <= result.size(); ++i)
		{
			cout << result[i] << endl;
		}
	}
	else
		cout << "匹配失败" << endl;

                


    2、搜索捕获

                
                (1)搜索给定字符串是否存在于模式匹配的子串之中,与match不同的是search是找是否存在子串,即模式串pattern是否是s的一部分。
                (2)和match一样,search也可以使用smatch result来记录结果,但不同的是result[0]记录的从左到右第一个匹配的子串
                (3)假如有多个子串符合模式,若想知道result[0]中存储的是第几个子串,可以用result.position()函数,返回数从0开始。
                (4)如果想遍历整个源串,匹配所有符合模式的子串,可以用string的迭代器,用result.second()更新迭代器位置。result[0].first返回的是查找结果子串在源串中的迭代器位置,second返回的是子串后面的位置,smatch.prefix表示匹配子串在源串的前缀,subfix表示后缀。
                (5)例子
       //有多个子串符合匹配模式
        regex pattern("\\d+");
	string s = "51x41+(5-13/2)x3";
	smatch result;
	string::const_iterator iter = s.cbegin();
	string::const_iterator iter_end = s.cend();
	while (regex_search(iter, iter_end, result, pattern))
	{
		cout << "查找成功:" << result[0]<< endl;
		iter = result[0].second;
	}

        //子串有多个捕获组
	cout << endl;
	regex p2("([a-zA-Z]{3})_(\\d{4})");
	string ss = "32sMq_19988abc_89912";
	iter = ss.cbegin();
	iter_end = ss.cend();
	while (regex_search(iter, iter_end, result, p2))
	{
		cout << "查找成功:" << result[0] << endl;
		for (int i = 1; i <= result.size(); ++i)
		{
			cout << result[i] << endl;
		}
		iter = result[0].second;
	}
                

                        

    3、替换

               
                
//正则替换     regex pattern("[a-zA-Z]{3}");     string s = "32sMQ_19988abc_199912" , ss;     cout << s << endl;     ss = regex_replace(s, pattern, "-ops-");     cout << ss << endl;     ss = regex_replace(s, pattern, "-ops$-");//$在替换里面是特殊字符,但是单个出现的时候似乎是不需要转义就可以正常输出     cout << ss << endl;     ss = regex_replace(s, pattern, "-ops$$$-");//这里再次验证了我的观点,第一个$是作为转义符出现的,所以这里的替换的结果只有两个$     cout << ss << endl;     ss = regex_replace(s, pattern, "-ops$&-");//$&表示被替换的子串,相当于缩写,举例来说,对于sMQ而言,$&就是sMQ     cout << ss << endl;     ss = regex_replace(s, pattern, "-ops$`-");//$`表示被替换的子串左侧的内容,举例来说,对于sMQ而言就是32;对于abc而言就是32sMQ_19988     cout << ss << endl;     ss = regex_replace(s, pattern, "-ops$'-");//$`表示被替换的子串右侧的内容,举例来说,对于sMQ而言就是_19988abc_199912;对于abc而言就是_199912     cout << ss << endl;     cout << endl;     regex p2("(([a-zA-Z]{3})_(\\d{4}))");     ss = regex_replace(s, p2, "$1");//$1是整个捕获结果,也就是sMQ_1998和abc_1999,本身替换本身,故就是源串没变     cout << ss << endl;     ss = regex_replace(s, p2, "$2");//$2是第一个捕获组,也就是sMQ和abc     cout << ss << endl;     ss = regex_replace(s, p2, "$3");//$3是1998和1999     cout << ss << endl;     ss = regex_replace(s, p2, "$3_$2");//调换了顺序,将匹配子串的sMQ_1998替换成了1998_sMQ,另外一个同理     cout << ss << endl;

                

    4、切割

                

	//正则切割
	string mail("123@qq.com,456@gmail.com,789@163.com,abc@my.com");
	regex reg(",");
	sregex_token_iterator pos(mail.begin(), mail.end(), reg, -1);//-1获取的是分割词前面的部分,0则是分割词
	decltype(pos) end;
	for (; pos != end; ++pos)
	{
		cout << pos->str() << endl;
	}

                
                

三、实例训练

    1.匹配IP   

        
void IP_match(string s)
{
	cout << "原内容为:\n" << s << endl;

	//位数对齐
	s = regex_replace(s, regex("(\\d+)"), "00$1");
	cout << "位数对齐后:\n" << s << endl;

	//去掉多的0
	s = regex_replace(s, regex("0*(\\d{3})"), "$1");//$1指的是最外层大括号的内容,比如00192是符合要求的子串,而192就是整个捕获组的内容
	cout << "去0后:\n" << s << endl;

	//取出ip
	regex reg("\\s");
	sregex_token_iterator pos(s.begin(),s.end(),reg,-1);
	decltype(pos) end;

	set<string> ip_set;
	for (; pos != end; ++pos)
	{
		ip_set.insert(pos->str());
	}

	cout << "最后结果:\n";
	//输出排序后的结果
	for (auto elem : ip_set)
	{
		cout << regex_replace(elem, regex("0*(\\d+)"), "$1") << endl;
	}


}
                


全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务