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,'\0');
    string sub("2019-03-8");
    
    //1.regex_replace 模板函数返回值实际上是新的字符串存入变量后尾部的指针位置, 置 0 是为了防止变量数据出错或乱码
    *regex_replace(result.begin(),str2.begin(),str2.end(),r2,sub)='\0';
    cout<<result.c_str()<<endl;

    //2.
    result.clear();
    result.resize(256,'\0');
    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
    */
}

 

posted on 2019-03-07 22:30  tianzeng  阅读(4551)  评论(0编辑  收藏  举报

导航