C++11 | 正则表达式(1)

C++11加入了正则表达式的支持,主要的类有:

  • basic_regex,模板类,代表一个正则表达式对象,有两个方便的实例化类,regex和wregex,分别代表窄字符串和宽字符串表示的正则表达式
  • sub_match,模板类,代表被子表达式匹配到的字符串,有csub_match、wcsub_match、ssub_match、wssub_match等四个实例化类方便使用
  • match_results,模板类,代表了一个正则表达式匹配的结果,其中包含所有子表达式的匹配结果,有cmatch、wcmatch、smatch、wsmatch四个常见的实例化类

主要的算法有:

  • regex_match,正则表达式要匹配整个字符串
  • regex_search,正则表达式可以匹配字符串中的一部分或全部
  • regex_replace,用一个字符串替换源字符串中匹配正则表达式的那部分子串

关于regex_match和regex_search有一个微妙的区别,下面的代码可以展示这一点:

    const char text[] = u8"abc";
    std::string strEx = "/home/foruok/20160406_153259.log";
    std::regex re1("/home/.*/[0-9]{8}_[0-9]{6}\.log");
    bool bMatch = std::regex_match(strEx, re1); // true
    std::cout << "regex_match - " << bMatch << '\n'; 
    bMatch = std::regex_search(strEx, re1); // true
    std::cout << "regex_search - " << bMatch << '\n'; 

    std::cout << "sub match test:\n";
    std::regex re2("[0-9]{8}_[0-9]{6}");
    bMatch = std::regex_match(strEx, re2); // false
    std::cout << "regex_match - " << bMatch << '\n';
    bMatch = std::regex_search(strEx, re2); // true
    std::cout << "regex_search - " << bMatch << '\n';

主要的迭代器有:

  • regex_iterator,模板类,可以枚举所有匹配结果,有cregex_iterator、wcregex_iterator、sregex_iterator、wsregex_iterator等实例化类。
  • regex_token_iterator,模板类,有cregex_token_iterator、wcregex_token_iterator、sregex_token_iterator、wsregex_token_iterator等实例化类。

regex_iterator和regex_token_iterator这两者的区别是,后者可以枚举未匹配的token。

当你构造迭代器时,regex_iterator内部会调用regex_search来做正则匹配并记录结果;当你递增迭代器时,regex_iterator会维护内部的submatch集合。

迭代器解复用后就是match。比如sregex_iterator it...;这样的代码,*it的类型就是smatch。

还有一些其他的方法、类,先不提了,怪复杂的。这些类库使用起来,也可能有一些让人迷惑的地方。我们先看最简单的应用。

我们使用regex、sregex_iterator、smatch来做正则匹配。

假设有一个字符串,类似“231;876;0;911”,我们想把用“;”分隔的整数都提取出来,就可以用正则表达式。

函数如下:

void ExtractNumbers(std::string &str,  vector < uint32_t> & numbers)
{
    std::regex numRegex("(\\d+)");
    auto numBegin = std::sregex_iterator(str.begin(),
                                            str.end(),
                                            numRegex);
    auto numEnd = std::sregex_iterator();
    for(std::sregex_iterator it = numBegin;
        it != numEnd; ++it)
    {
        std::smatch match = *it;
        std::string matchStr = match.str();
        numbers.push_back(std::stoul(matchStr));
    }
}

测试代码可能是这样的:

    std::string strNumbers = "0;1;234";
    std::vector<uint32_t> numbers;
    std::cout << "\nnumbers:\n  ";
    ExtractNumbers(strNumbers, numbers);
    for(auto i : numbers) std::cout << i << " ";
    std::cout << std::endl;

使用迭代器是最简单的方法。我们也可以直接使用regex_search、regex_match,后面再举例子。

关于正则表达式本身,可以参考:正则表达式30分钟入门


参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

foruok

你可以选择打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值