• Boost学习之正则表达式--regex


    Boost学习之正则表达式--regex【转】【1】
    http://blog.csdn.net/alsm168/article/details/6478920
    Boost学习之正则表达式--regex【转】【2】 
    http://blog.csdn.net/alsm168/article/details/6478921

     

    boost::regex类为C++提供了完整的正则表达式支持,并且已被接收为C++0x标准库。它同时也在Boost库中扮演着极重要的角色,不少Boost子库都需要它的支持,有不少人甚至就是为了它才下载使用Boost的。

    注意使用Boost.Regex需要预先编译

    完整编译请参考本站

    编译Boost的文章

    如果只要编译Regex库,有两种方法(参考链接):

    1. 在Boost根目录下运行bjam --toolset=<编译器名> --with-regex 其它参数
    2. <boost>/libs egex/build里,找到对应编译器的makefile,然后make -f xxxx.mak
    使用

    Boost.Regex手里有七种武器和两大法宝


    其中的七种武器是:


    regex_match 函数 regex_search 函数 regex_replace 函数 regex_format 函数 regex_grep 函数 regex_split 函数 RegEx 类

    每种武器都又有诸多变化(

    每个函数都分别以C字符串类型std::string类型迭代器类型作为参数重载

    ),不过后面四种武器因年久失修已不建议使用.


    两大法宝是:


    regex_iterator 迭代器 regex_token_iterator 迭代器

    这两大法宝是整个Boost.Regex的灵魂,用熟它们以后那是“摘花飞叶即可伤人”啊~~


    回到正题,下面边写边学。所需头文件: #include <boost/regex.hpp>

     

    示例代码:

    先准备一个测试用的数据备用,如果各位有雅兴可以参考本站的另一篇文章《

    Google Testing

    》使用Google Testing框架来做这个实验,花一样时间学两样啊~~


    1. #include <iostream>
    2. #include <boost/regex.hpp>
    3.  
    4. using namespace std;
    5. int main(int argc, char* argv[])
    6. {    //( 1 )   ((  3  )  2 )((  5 )4)(    6    )   
    7.     //(/w+)://((/w+/.)*/w+)((//w*)*)(//w+/./w+)?
    8.     //^协议://网址(x.x...x)/路径(n个/字串)/网页文件(xxx.xxx)
    9.     const char *szReg = "(//w+)://((//w+//.)*//w+)((///w*)*)(///w+//.//w+)?";
    10.     const char *szStr = "http://www.cppprog.com/2009/0112/48.html";
    11.  
    12.     //练习代码...
    13.    
    14.    
    15.     cin.get(); //暂停
    16. }
     

    1.字符串匹配

    要确定一行字符串是否与指定的正则表达式匹配,使用

    regex_match


    下面这个代码可以验证szStr字串(定义在上面)是否与szReg匹配。


    1. {    //字符串匹配
    2.     boost::regex reg( szReg );
    3.     bool r=boost::regex_match( szStr , reg);
    4.     assert(r); //是否匹配
    5. }
     

    boost::regex

    的构造函数中还可以加入标记参数用于指定它的行为,如:


    1. //指定使用perl语法(默认),忽略大小写。
    2. boost::regex reg1( szReg, boost::regex::perl|boost::regex::icase );
    3. //指定使用POSIX扩展语法(其实也差不多)
    4. boost::regex reg2( szReg, boost::regex::extended );
     


    下面这个代码不仅验证是否匹配,而且可以从中提取出正则表达式括号对应的子串。


    1. {    //提取子串
    2.     boost::cmatch mat;
    3.     boost::regex reg( szStr );
    4.     bool r=boost::regex_match( szStr, mat, reg);
    5.     if(r) //如果匹配成功
    6.     {
    7.         //显示所有子串
    8.         for(boost::cmatch::iterator itr=mat.begin(); itr!=mat.end(); ++itr)
    9.         {
    10.             //       指向子串对应首位置        指向子串对应尾位置          子串内容
    11.             cout << itr->first-szStr << ' ' << itr->second-szStr << ' ' << *itr << endl;
    12.         }
    13.     }
    14.     //也可直接取指定位置信息
    15.     if(mat[4].matched) cout << "Path is" << mat[4] << endl;
    16. }
     

    其中,

    boost::cmatch

    是一个针对

    C字符串

    的特化版本,它还有另三位兄弟,如下:


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

    可以把

    match_results

    看成是一个

    sub_match

    的容器,同时它还提供了

    format

    方法来代替

    regex_format

    函数。


    一个

    sub_match

    就是一个子串,它从

    std::pair<BidiIterator, BidiIterator>

    继承而来,这个

    迭代器pair

    里的

    first

    second

    分别指向了这个子串开始和结尾所在位置。同时,

    sub_match

    又提供了

    str(),length()

    方法来返回整个子串。


     

    2.查找字符串 regex_match

    只验证是否完全匹配,如果想从一大串字符串里找出匹配的一小段字符串(

    比如从网页文件里找超链接

    ),这时就要使用

    regex_search

    了。


    下面这段代码从szStr中找数字


    1. //查找
    2.     boost::cmatch mat;
    3.     boost::regex reg( "//d+" );    //查找字符串里的数字
    4.     if(boost::regex_search(szStr, mat, reg))
    5.     {
    6.         cout << "searched:" << mat[0] << endl;
    7.     }
    8. }
     

     

    3.替换 regex_replace

    提供了简便的方法来部分替换源字符串


    正则表达式中,使用

    $1~$9

    /1~/9

    )表示第几个子串,

    $&

    表示整个串,

    $`

    表示第一个串,

    $'

    表示最后未处理的串。


    1. //替换1,把上面的HTTP的URL转成FTP的
    2.     boost::regex reg( szReg );
    3.     string s = boost::regex_replace( string(szStr), reg, "ftp://$2$5");
    4.     cout << "ftp site:"<< s << endl;
    5. }
     

    正则表达式中,使用

    (?1~?9新字串)

    表示把第几个子串替换成新字串


    1. //替换2,使用format_all参数把<>&全部转换成网页字符
    2.     string s1 = "(<)|(>)|(&)";
    3.     string s2 = "(?1&lt;)(?2&gt;)(?3&amp;)";
    4.     boost::regex reg( s1 );
    5.     string s = boost::regex_replace( string("cout << a&b << endl;"), reg, s2, boost::match_default | boost::format_all);
    6.     cout << "HTML:"<< s << endl;
    7. }
  • 相关阅读:
    grep
    virtualbox共享文件夹无法创建软链接的解决方法
    openH264的双向链表实现
    openH264构建过程
    Ninja构建系统入门
    ubuntu上安装meson & 如何使用meson编译C代码
    ln: failed to create symbolic link ‘libopenh264.so.6’: Operation not permitted
    RAII-资源获取即初始化
    可变参数实现原理-参数栈
    一个统计多文件单行字符串出现次数QT实现
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318442.html
Copyright © 2020-2023  润新知