2010-04-18 7 views
1

j'ai ce programme C++ (en fait, il est juste un extrait):PCRE problème Matche multi ligne

#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; 
} 

Comme vous pouvez le voir, je suis en train de faire correspondre les liens HTML à l'intérieur d'un tampon avec l'expression régulière (le \\s est \s échappé pour les chaînes C/C++). Mais, même si dans le tampon il y a 3 liens et l'expression rationnelle est compilé avec les drapeaux PCRE_CASELESS et PCRE_MULTILINE, je correspondent un seul élément:

Match : example_link_1 

Note: Je commence la boucle vient index 1 parce que la bibliothèque PCRE renvoie la chaîne qui correspond (pas le match lui-même) en tant que premier élément, et les correspondances suivantes.

Quel est le problème avec ce code? L'expression rationnelle elle-même je pense que c'est correct (essayé en PHP par exemple).

Répondre

2

Eh bien, ce n'est pas censé retourner tous les résultats. Pensez-y, vous demandez le compte de capture, qui est quelque chose comme un ou deux (c'est-à-dire, le match entier et une sous-expression, ou juste la sous-expression, je ne me souviens pas, je devine deux). Et comment vous attendez-vous à savoir combien de matches se trouvent dans la chaîne que vous n'avez jamais passée? Et vous ne vous attendez pas à ce que la chose retourne trois matchs dans le tableau, n'est-ce pas? Et si vous en avez eu trois mille?

Cela fait longtemps que je n'ai pas traité pcre api, mais je pense que vous avez besoin de boucler et de faire correspondre le reste de la chaîne.

+0

J'ai cherché cette "boucle" et trouvé la solution, merci! :) –

+0

vous êtes les bienvenus ;-) –