代码之家  ›  专栏  ›  技术社区  ›  Simone Margaritelli

PCRE多线匹配问题

  •  1
  • Simone Margaritelli  · 技术社区  · 16 年前

    我有这个C++程序(实际上它只是一个片段):

    #include <iostream>
    #include <pcre.h>
    #include <string>
    
    using namespace std;
    
    int main(){    
        string pattern = "<a\\s+href\\s*=\\s*\"([^\"]+)\"",
               html = "<html>\n"
                      "<body>\n"
                      "<a href=\"example_link_1\"/>\n"
                      "<a href=\"example_link_2\"/>\n"
                      "<a href=\"example_link_3\"/>\n"
                      "</body>\n"
                      "</html>";
        int            i, ccount, rc,
                    *offsets,
                     eoffset;
        const char  *error;
        pcre         *compiled;
    
        compiled = pcre_compile( pattern.c_str(), PCRE_CASELESS | PCRE_MULTILINE, &error, &eoffset, 0 );
        if( !compiled ){
            cerr << "Error compiling the regexp!!" << endl;
            return 0;
        }
    
        rc = pcre_fullinfo( compiled, 0, PCRE_INFO_CAPTURECOUNT, &ccount );
    
        offsets = new int[ 3 * (ccount + 1) ];
    
        rc = pcre_exec( compiled, 0, html.c_str(), html.length(), 0, 0, offsets, 3 * (ccount + 1) );
    
        if( rc >= 0 ){
            for( i = 1; i < rc; ++i ){
                cout << "Match : " << html.substr( offsets[2*i], offsets[2*i+1] - offsets[2*i] ) << endl;
            }
        }
        else{
            cout << "Sorry, no matches!" << endl;
        }
    
        delete [] offsets;
    
        return 0;
    }
    

    \\s \s 为C/C++字符串逃逸。 但是,即使缓冲区中有3个链接,并且regexp是用PCRE\u CASELESS和PCRE\u MULTILINE标志编译的,我也只匹配一个元素:

    Match : example_link_1
    

    这个代码怎么了?regexp本身我认为是正确的(例如在PHP中尝试过)。

    1 回复  |  直到 16 年前
        1
  •  2
  •   Michael Krelin - hacker    16 年前

    嗯,它不应该归还所有的火柴。想想看,你要求capturecount,大概是一个或两个(也就是说,要么是整个匹配和一个子表达式,要么只是子表达式,我不记得了,我猜是两个)。你怎么能指望它知道你从未传递给它的字符串中有多少个匹配项?你不希望它在数组中返回三个匹配项,是吗?如果你有三千?

    我已经有一段时间没有处理pcreapi了,但是我认为您需要再次循环并与字符串的其余部分进行匹配。