PCRE многострочная проблема - PullRequest
1 голос
/ 19 апреля 2010

У меня есть эта программа на 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;
}

Как видите, я пытаюсь сопоставить html-ссылки внутри буфера с заданным регулярным выражением (\\s - это \s, экранированный для строк C / C ++). Но даже если в буфере есть 3 ссылки и регулярное выражение скомпилировано с флагами PCRE_CASELESS и PCRE_MULTILINE, я сопоставляю только один элемент:

Match : example_link_1

Примечание: я запускаю цикл с индексом 1, потому что библиотека pcre возвращает строку, которая соответствует (не соответствует самому совпадению), в качестве первого элемента, и совпадения следуют.

Что не так с этим кодом? Само регулярное выражение, я думаю, это правильно (пробовал в PHP, например).

1 Ответ

2 голосов
/ 19 апреля 2010

Ну, он не должен возвращать все совпадения. Подумайте об этом, вы запрашиваете capturecount, что-то вроде одного или двух (то есть либо всего совпадения и одного подвыражения, либо просто подвыражения, я не помню, я бы предположил два). И как вы ожидаете, что он узнает, сколько совпадений в строке вы никогда не передавали? И вы не ожидаете, что вещь вернет три совпадения в массиве, не так ли? А если у тебя было три тысячи?

Прошло много времени с тех пор, как я имел дело с pcre api, но я думаю, что вам нужно повторить цикл и снова сопоставить остальную часть строки.

...