zoukankan      html  css  js  c++  java
  • C++ regex库常用函数及实例

    简介

    regex是C++标准库中用于正则表达式(regular expression)的部分。

    大致有如下常用组件:

    组件名称 作用
    regex 表示有一个正则表达式的类
    regex_match 将一个字符序列与一个正则表达式匹配
    regex_search 寻找第一个与正则表达式匹配的子序列
    regex_replace 使用给定格式替换一个正则表达式
    sregex_iterator 迭代器适配器,内部调用regex_search来遍历一个string中所有匹配的子串
    smatch 容器类,保存在string中搜索的结果
    ssub_match string中匹配的子表达式的结果
    示例

    在下面一个简单的例子里使用一些组件

    #include<regex>
    #include<iostream>
    using namespace std;
    //正则表达式
    void main()
    {
    	string pattern = "^([a-z]|_)[[:alnum:]]+";
        //开头的^表示从字符串开头开始匹配,|表示或,alnum表示字母或数字,+表示至少重复一次
    	regex r(pattern, regex::icase);//初始化正则表达式类,icase表示忽略大小写
    	string s("Asff");
    	smatch results;//用于保存成功匹配的相关信息
    	if (regex_search(s, results, r))
    		cout << results.str() << endl;
    	s="_qwer";
    	if (regex_search(s, results, r))
    		cout << results.str() << endl;
    	s="9sff";
    	if (regex_search(s, results, r))
    		cout << results.str() << endl;
    }
    

    输出如下:

    Asff
    _qwer
    

    ​ 在这个例子里,我们通过regex_search函数,查找第一个与正则表达式匹配的子序列,smatch对象将会保存匹配结果的相关细节。

    异常

    ​ C++的正则表达式并不是由C++编译器解析,而是在运行时由相关库函数进行解析,因此如果正则表达式存在语法错误,程序将会抛出名为regex_error的异常。

    捕获异常并且输出错误信息:

    void fun()
    {
        try{
        	regex r("([[:alpha:]]");        
        }catch(regex_error e)
        {
            cout<<e.what()<<"
    ";//错误信息
            cout<<e.code()<<endl;//错误码
    	}
    }
    
    char数组传参

    ​ regex_search函数的输入序列参数可以传入string或者以''结尾的字符数组,传入string时,使用smatch对象接受匹配成功的相关信息;而传入char*时,如果还使用smatch对象就会编译失败,此时需要使用cmatch对象才能编译成功。

    使用regex迭代器来获取所有匹配

    sregex_iterator的部分操作如下表

    操作 作用
    sregex_iterator it(b,e,r); b,e分别为输入序列的迭代器起始尾后位置,将sregex_iterator对象it定位到输入中第一个匹配的位置
    sregex_iterator it_end; 无参构造函数生成尾后迭代器
    *it 解引用,根据最后一个调用regex_search的结果,返回一个smatch对象的引用
    it-> 间接引用smatch的成员函数
    ++it 在当前匹配位置调用regex_search,并返回递增后的迭代器
    it++ 在当前匹配位置调用regex_search,但返回递增前的迭代器
    it1==it2 如果都是尾后迭代器,则相等。非尾后迭代器如果由相同的输入序列和相同的regex对象构造,则相等
    it1!=it2 不符合相等的情况
    综合示例

    ​ 综合上面的知识,我们可以编写一个提取合法ipv4地址的小程序,其中regex对象pattern中使用\的原因是:一个用于转义'('、')'、'd'(表示整数)等符号,另一个是由于C++中为转义字符,\才表示一个符号。

    #include<regex>
    #include<iostream>
    using namespace std;
    
    bool validSubExepression(const smatch& s)
    {//检查表达式是否合法
    	if (s[1].matched)//如果有左括号,那么要求一定要有匹配的右括号
    		return s[9].matched && s[3].str() == s[5].str() && s[5].str() == s[7].str();//且3个分隔符要相同
    	else//如果没有左括号,那么要求没有右括号
    		return !s[9].matched && s[3].str() == s[5].str() && s[5].str() == s[7].str();
    }
    
    bool overflow(const smatch& s)
    {//ip地址是否溢出
    	for (int i = 2; i <= 8; i++)
    	{
    		int number = atoi(s.str().c_str());
    		if (number > 255)
    			return true;
    	}
    	return false;
    }
    
    int main()
    {
    	string pattern =
    		"(\()?(\d{1,3})([-. ])?(\d{1,3})([-. ])?(\d{1,3})([-. ])?(\d{1,3})(\))?";
    	string ipaddress = "192.168.1.2 (123.233.111.33 114.114.114.114) (8-8.8.8) 7-8-9-10 172 0 0 1 888.224.525.244 192&168&1&1";
    	string fmt = "($2.$4.$6.$8)";//格式化,子表达式2,4,6,8原样输出,其余部分按(...)格式输出
    	try
    	{
    		regex r(pattern);
    		for (sregex_iterator it(ipaddress.begin(), ipaddress.end(), r), end_it; it != end_it; ++it)
    		{
    			if (!overflow(*it))
    			{
    				if (validSubExepression(*it))
    				{
    					cout << "Before format:" << it->str() << endl;
    					cout << "After  format:" << regex_replace(it->str(), r, fmt) << endl << endl;
    				}
    				else
    				{
    					cout << "not valid:" << endl;
    					cout << "Before format:" << it->str() << endl;
    					cout << "After  format:" << regex_replace(it->str(), r, fmt) << endl << endl;
    				}
    			}
    			else
    				cout << "overflow" << endl;
    		}
    	}
    	catch (regex_error e)
    	{
    		cout << "(error code:" << e.code() << ")" << endl;//输出错误代码
    		cout << e.what() << endl;                         //输出错误信息
    	}
    }
    
  • 相关阅读:
    hdu 1455 N个短木棒 拼成长度相等的几根长木棒 (DFS)
    hdu 1181 以b开头m结尾的咒语 (DFS)
    hdu 1258 从n个数中找和为t的组合 (DFS)
    hdu 4707 仓鼠 记录深度 (BFS)
    LightOJ 1140 How Many Zeroes? (数位DP)
    HDU 3709 Balanced Number (数位DP)
    HDU 3652 B-number (数位DP)
    HDU 5900 QSC and Master (区间DP)
    HDU 5901 Count primes (模板题)
    CodeForces 712C Memory and De-Evolution (贪心+暴力)
  • 原文地址:https://www.cnblogs.com/sgawscd/p/13794818.html
Copyright © 2011-2022 走看看