下面的 代码是 boost 正则匹配后 取出 匹配字符  //提取子串
  boost::cmatch mat;
  boost::regex reg( szStr );
  bool r=boost::regex_match( szStr, mat, reg);
  if(r) //如果匹配成功
  {
  //显示所有子串
  for(boost::cmatch::iterator itr=mat.begin(); itr!=mat.end(); ++itr)
  {
  //这里面的要怎么写 怎么读取出匹配的字符,别人说是在 *itr 或mat[0]中,但这两个数据都定义是模板。我用AfxMessageBox()把这两个值输出 都报错,说是类型不对,我是VS2010 怎么样才能正常输出 ,谢谢大家了。可以付费  我的QQ 29 29 24290
  }
  }

解决方案 »

  1.   

    首先声明,这个我没学过:
    --------------------分割线---------------------------boost::regex的用法 * boost::regex的用法  bool validate_card_format(const std::string s) 

       static const boost::regex e("(\\d{4}[- ]){3}\\d{4}"); 
       return regex_match(s, e); 
    }     * boost::regex的默认正则表达式语法是perl语法      boost::regex支持perl regular表达式、POSIX-Extended regular表达式和POSIX-Basic Regular表达式,但默认的表达式语法是perl语法,如果要使用其余两种语法需要在构造表达式的时候明确指定。     例如,下面两种方法效果相同 
        // e1 is a case sensitive Perl regular expression:  
        // since Perl is the default option there's no need to explicitly specify the syntax used here: 
          boost::regex e1(my_expression); 
        // e2 a case insensitive Perl regular expression: 
        boost::regex e2(my_expression, boost::regex::perl|boost::regex::icase);     * perl正则表达式语法          perl正则表达式语法可参见《perl语言入门》第7、8、9章或boost的文档。这里列出的语法是不全面的。         . 任意字符;使用match_no_dot_null标志时不匹配NULL字符; 使用match_not_dot_newline时不匹配换行字符         ^ 匹配行的开始 
            $ 匹配行的结束 
            * 重复零次或则更多,例如a*b可匹配b,ab,aab,aaaaaaab 
            + 重复一次以上,例如a+b可匹配ab,aab,aaaaaaaab。但不能匹配b了 
            ? 零次或则一次,例如ca?b匹配cb,cab但不匹被caab     
            a{n} 匹配字符'a'重复n次 
            a{n,},字符a重复n次以上(含n次) 
            a{n,m} a重复n到m次(含)         *?   匹配前一个原子零次以上 
            +?   匹配前一个原子一次以上 
            ??   匹配前一个原子零次以上 
            {n,}?  匹配前一个原子n次以上(含) 
            {n,m?  匹配前一个原子n到m次(含)         | 或操作,例如ab(d|ef)匹配abd或则abef 
            [] 字符集操作,例如[abc]将匹配任何单个字符'a','b','c' 
            [a-d],表示a、b、c、d 
            ^否操作,例如[^a-c]表示a至c之外的所有字符     * boost::regex对unicode编码的支持      boost::regex使用ICU来实现对unicode及unicode变种的支持,这需要在编译boost的时候指出是否使用ICU 以及ICU所在的目录。否则编译出来的boost::regex不支持unicode编码。其中boost::wregex支持unicode编码的搜索,如果要搜索UTF-8、UTF-16、UFT-32编码的字符串,则要用boost::u32regex。注意boost::wregex只能支持 unicode编码,不能支持uft编码。     * 搜索时如何忽略大小写      如果要在搜索时忽略大小写(即大小写不敏感),则要用到表达式选项boost::regex::icase,例如: boost::regex e2(my_expression, boost::regex::perl|boost::regex::icase); 
    ----------------------------------------------- 
    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. } #include <iostream> 
    #include <boost/regex.hpp> using namespace std; 
    int main(int argc, char* argv[]) 
    {    //( 1 )   ((  3  )  2 )((  5 )4)(    6    )    
        //(\w+)://((\w+\.)*\w+)((/\w*)*)(/\w+\.\w+)? 
        //^协议://网址(x.x...x)/路径(n个\字串)/网页文件(xxx.xxx) 
        const char *szReg = "(\\w+)://((\\w+\\.)*\\w+)((/\\w*)*)(/\\w+\\.\\w+)?"; 
        const char *szStr = "http://www.cppprog.com/2009/0112/48.html";     //练习代码... 
        
        
        cin.get(); //暂停 

    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 reg( szReg ); 
            bool r=boost::regex_match( szStr , reg); 
            assert(r); //是否匹配 
        } 
    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 ); //指定使用perl语法(默认),忽略大小写。 
    boost::regex reg1( szReg, boost::regex::perl|boost::regex::icase ); 
    //指定使用POSIX扩展语法(其实也差不多) 
    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 mat; 
            boost::regex reg( szStr ); 
            bool r=boost::regex_match( szStr, mat, reg); 
            if(r) //如果匹配成功 
            { 
                //显示所有子串 
                for(boost::cmatch::iterator itr=mat.begin(); itr!=mat.end(); ++itr) 
                { 
                    //       指向子串对应首位置        指向子串对应尾位置          子串内容 
                    cout << itr->first-szStr << ' ' << itr->second-szStr << ' ' << *itr << endl; 
                } 
            } 
            //也可直接取指定位置信息 
            if(mat[4].matched) cout << "Path is" << mat[4] << endl; 
        } 
    其中,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. }     { //查找 
            boost::cmatch mat; 
            boost::regex reg( "\\d+" );    //查找字符串里的数字 
            if(boost::regex_search(szStr, mat, reg)) 
            { 
                cout << "searched:" << mat[0] << endl; 
            } 
        }   
    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,把上面的HTTP的URL转成FTP的 
            boost::regex reg( szReg ); 
            string s = boost::regex_replace( string(szStr), reg, "ftp://$2$5"); 
            cout << "ftp site:"<< s << endl; 
        } 
    正则表达式中,使用(?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. }     { //替换2,使用format_all参数把<>&全部转换成网页字符 
            string s1 = "(<)|(>)|(&)"; 
            string s2 = "(?1&lt;)(?2&gt;)(?3&amp;)"; 
            boost::regex reg( s1 ); 
            string s = boost::regex_replace( string("cout << a&b << endl;"), reg, s2, boost::match_default | boost::format_all); 
            cout << "HTML:"<< s << endl; 
        } 
    --------------------分割线-------------------------------
      

  2.   

    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. }  
    ---------------------分割线---------------------
    既然能用cout输出“itr->first-szStr”等内容,
    就应该可以用
    CString 的Format 格式化输出,
    剩下的就是找找每个变量的数据类型了。