zoukankan      html  css  js  c++  java
  • c++正则表达式

    basic_regex

      该类封装了正则表达式的解析和编译,是正则表达式的基本类。一般有两种特化regex和wregex

    template<class _Elem,
        class _RxTraits = regex_traits<_Elem> >
        class basic_regex
            : public _Regex_base
        {   //
    ...
    typedef basic_regex<char> regex;
    typedef basic_regex<wchar_t> wregex;

    match_results

      该类保存了正则表达式匹配的结果。match_results为正则表达式的匹配结果提供了一个类似容器的视图,可以用size()和empty()判断匹配结果中子表达式的数量,operator[]返回低i个子表达式。如果i==0,则返回整个表达式的匹配对象。

    typedef match_results<const char *> cmatch;
    typedef match_results<const wchar_t *> wcmatch;
    typedef match_results<string::const_iterator> smatch;
    typedef match_results<wstring::const_iterator> wsmatch; 

    sub_match

      该模板类是一个类似迭代器的对象,继承自std::pair,用来表示一个与子表达式匹配的序列,可以把它当作一个字符区间。

    regex_replace

    template<class _RxTraits,
        class _Elem>
        _STD basic_string<_Elem> regex_replace(
            const _STD basic_string<_Elem>& _Str,
            const basic_regex<_Elem, _RxTraits>& _Re,
            const _STD basic_string<_Elem>& _Fmt,
            regex_constants::match_flag_type _Flgs =
                regex_constants::match_default)
        {   // search and replace
    ...

      正则表达式的语法:http://help.locoy.com/Document/Learn_Regex_For_30_Minutes.htm

    #include <iostream>
    #include <regex>
    using namespace std;
    
    int main()
    {
        
        //--------------std::regex_match: 正则表达式需要匹配整个字符串序列, 也就是说正则表达式要与
        //字符串完全匹配, 因此, 它是单次匹配, 否则匹配失败.  它还可以获取子匹配的组
        string str("adfd-89-@-.");
        //这里 "()" 用于捕获组, 捕获组的编号是按照 "(" 出现的顺序, 从左到右, 从1开始进行编号的 
        regex partten("([a-z]{4})-(\d{2}-@-\.)");
        
        //1.只匹配是否符合正则表达式 
        cout<<regex_match(str,partten)<<endl;
        
        //2-1.匹配是否符合正则表达式并将其他一次捕获到数组 sm[0]是匹配的正则表达式结果;match_results<string::const_iterator> sm; 
        smatch sm;
        if(regex_match(str.cbegin(),str.cend(),sm,partten))
        {
            for(match_results<string::const_iterator>::const_iterator it=sm.begin();it!=sm.end();++it)
                cout<<it->length()<<": "<<it->str()<<endl;
        }
        
        //2-2.用类match_results存储结果 
        match_results<string::iterator> res;
        if(regex_match(str.begin(),str.end(),res,partten))
        {
            for(auto it=res.begin();it!=res.end();++it)
                cout<<it->length()<<": "<<it->str()<<endl;
        }
        
        //3.cmatch match_resluts<const char*>
        cmatch cm;
        if(regex_match(str.c_str(),cm,partten))
        {
            for(match_results<const char *>::const_iterator it=cm.begin();it!=cm.end();++it)
            {
                cout<<it->length()<<": "<<it->str()<<endl;
            }    
        }
        
        //4.
        cout<<regex_match(str.c_str(),partten)<<endl;
        
        //5.
        match_results<string::const_iterator> ress;
        if(regex_match(str,ress,partten))
        {
            for(int i=0;i<ress.size();++i)
            {
                //sub_match: 子匹配, match_results里面都存放的是sub_match
                //sub_match 可以理解为 std::pair 的扩展, 它继承了 std::pair,
                //其中 first 实际上存放的是获取的字符串头指针地址, second 为尾指针地址
                ssub_match sub=ress[i];
                cout<<sub.length()<<": "<<sub.str()<<endl;
            }
        }
        
        
        //------------std::regex_search: 搜素正则表达式参数, 但它不要求整个字符序列完全匹配. 
        //而且它只进行单次搜索, 搜索到即停止继续搜索, 不进行重复多次搜索.
        //这里 "()" 用于捕获组, 捕获组的编号是按照 "(" 出现的顺序, 从左到右, 从1开始进行编号的
        string str1("Data-Time:2019-03-07-23:20~2019-03-08-23:59");
        regex r("(\d{4}-)(\d{2}-)(\d{2})");
        
        //1.第0组一般是整个正则表达式匹配结果, 其他依次是捕获组的结果, 它不进行重复多次搜索
        match_results<string::iterator> res1;
        if(regex_search(str1.begin(),str1.end(),res1,r))
        {
            match_results<string::iterator>::const_iterator it;
            for(it=res1.begin();it!=res1.end();++it)
                cout<<it->length()<<": "<<it->str() <<endl;
        }
        
        //2.显示是否有搜索到符合正则表达式的结果
        cout<<regex_search(str1.begin(),str1.end(),r)<<endl;
        
        //3.与1相同。但是此次用的是smatch,
        smatch sm1;
        if(regex_search(str1.cbegin(),str1.cend(),sm1,r)) 
        {
            for(auto it=sm1.begin();it!=sm1.end();++it)
                cout<<it->length()<<": "<<it->str()<<endl;
        }
        
        //4.与1相同。但是此次用的是cmatch
        cmatch cm1;
        if(regex_search(str1.c_str(),cm1,r))
        {
            for(int i=0;i<cm1.size();++i)
            {
                csub_match cs=cm1[i];
                cout<<cs.length()<<": "<<cs.str()<<endl;
                
            }
        }
        
        //5.
        cout<<regex_search(str1,r)<<endl;
        
        //6.
        cout<<regex_search(str1.c_str(),r)<<endl;
        
        
        //--------------egex_replace: 多次搜索整个正则表达式(不考虑捕获组),然后替换正则表达式匹配到的结果
        string str2("Date:2019-03-7~2019-03-20");
        regex r2("\d{4}-\d{2}-\d{2}");
        //结果集合和替换的字符
        string result(256,'');
        string sub("2019-03-8");
        
        //1.regex_replace 模板函数返回值实际上是新的字符串存入变量后尾部的指针位置, 置 0 是为了防止变量数据出错或乱码
        *regex_replace(result.begin(),str2.begin(),str2.end(),r2,sub)='';
        cout<<result.c_str()<<endl;
    
        //2.
        result.clear();
        result.resize(256,'');
        result=regex_replace(str2,r2,sub);
        cout<<result.c_str()<<endl;
        return 0;
    }

    regex_iterator

    void iterator()
    {
        //std::regex_iterator
        //std::regex_iterator: 用于多次重复匹配, 不分组, 只进行多次匹配整个正则表达式,可获取整个正则表达式的结果
       
        std::string text = "Date:2017-10-10 ~ 2017-10-15";
     
        //构造正则表达式
        //这里 "()" 用于捕获组, 捕获组的编号是按照 "(" 出现的顺序, 从左到右, 从1开始进行编号的
        std::string pattern = "(\d{4})-(\d{2}-(\d{2}))";
        std::regex express(pattern);
     
        std::regex_iterator<std::string::const_iterator> begin(text.cbegin(), text.cend(), express);
        //std::sregex_iterator == std::regex_iterator<std::string::const_iterator>
        for (auto iter = begin; iter != std::sregex_iterator(); iter++)
        {
            std::cout << iter->length() << ": " << iter->str() << std::endl;
        }
        /*输出
        10: 2017-10-10
        10: 2017-10-15
        */
    }

    regex_token_iterator

    void token_iterator()
    {
        /////////////////////////////////////////////////////////////////////////
        //std::regex_token_iterator
        //std::regex_token_iterator: 用于多次匹配正则表达式, 它可以获取整个正则表达式
        //的结果, 也可以获取正则表达式的前缀, 还可以获取正则表达式的分组子匹配
     
        std::string text = "Date:2017-10-10 ~ 2017-10-15";
     
        //构造正则表达式
        //这里 "()" 用于捕获组, 捕获组的编号是按照 "(" 出现的顺序, 从左到右, 从1开始进行编号的
        std::string pattern = "(\d{4})-(\d{2}-(\d{2}))";
        std::regex express(pattern);
     
        /*构造函数2-1*/
        //(多次匹配)显示正则表达式匹配, 即参数 4 等于 0
        std::regex_token_iterator<std::string::const_iterator> begin2_1(text.cbegin(), text.cend(), express);
        //std::sregex_token_iterator == std::regex_token_iterator<std::string::const_iterator>
        for (auto iter = begin2_1; iter != std::sregex_token_iterator(); iter++)
        {
            std::cout << iter->length() << ": " << iter->str() << std::endl;
        }
        /*输出
        10: 2017-10-10
        10: 2017-10-15
        */
     
        /*构造函数2-2*/
        //(多次匹配)显示正则表达式匹配到的前缀, -1 则表示只显示前缀
        std::regex_token_iterator<std::string::const_iterator> begin2_2(text.cbegin(), text.cend(), express, -1);
        for (auto iter = begin2_2; iter != std::sregex_token_iterator(); iter++)
        {
            std::cout << iter->length() << ": " << iter->str() << std::endl;
        }
        /*输出
        5: Date:
        3:  ~
        */
     
        /*构造函数2-3*/
        //(多次匹配)显示正则表达式子匹配, 3 表示第三组子匹配
        std::regex_token_iterator<std::string::const_iterator> begin2_3(text.cbegin(), text.cend(), express, 3);
        for (auto iter = begin2_3; iter != std::sregex_token_iterator(); iter++)
        {
            std::cout << iter->length() << ": " << iter->str() << std::endl;
        }
        /*输出
        2: 10
        2: 15
        */
     
        /*构造函数3*/
        //(多次匹配)显示正则表达式匹配到的前缀和子匹配, -1 表示前缀, 2 表示第二个子匹配
        std::vector<int> vec;
        vec.push_back(-1);
        vec.push_back(2);
        std::regex_token_iterator<std::string::iterator> begin3(text.begin(), text.end(), express, vec);
        for (auto iter = begin3; iter != std::regex_token_iterator<std::string::iterator>(); iter++)
        {
            std::cout << iter->length() << ": " << iter->str() << std::endl;
        }
        /*输出
        5: Date:
        5: 10-10
        3:  ~
        5: 10-15
        */
     
        /*构造函数4*/
        //(多次匹配)显示正则表达式匹配到的前缀和整个正则表达式匹配, -1 表示前缀, 0 表示匹配整个正则表达式.
        int arr[] = {-1, 0};
        std::regex_token_iterator<std::string::iterator> begin4(text.begin(), text.end(), express, arr);
        for (auto iter = begin4; iter != std::regex_token_iterator<std::string::iterator>(); iter++)
        {
            std::cout << iter->length() << ": " << iter->str() << std::endl;
        }
        /*输出
        5: Date:
        10: 2017-10-10
        3:  ~
        10: 2017-10-15
        */
    }
  • 相关阅读:
    [转]cmd-bat批处理命令延时方法
    chrome pyv8下载
    win10锁屏壁纸路径
    MongoDB系列—— Window 搭建Mongodb 集群
    JS判断所有IE浏览器所有版本
    网页中引用优酷视频默认自动播放超清
    SQL 还原或备份失败数据库变成单个用户模式无法访问
    百度webuploader 上传演示例子
    SQL Server 如何更改SQL Server和windows身份方式验证
    已经阻止此发布者在你的计算机上运行软件
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10492932.html
Copyright © 2011-2022 走看看