2013-03-06 2 views
3

J'utilise la bibliothèque regex PCRE en C (http://www.pcre.org/) pour analyser et faire correspondre ma chaîne HTML. Pour simplifier ma question, supposons que je suis la chaîne source: "aaa: bbbb:", et mon modèle: un (*.?): | B:, le symbole (*.?)? indiquent que c'est un match non-gourmand, de sorte que la réponse devrait être deux matchups: l'une est "aaa:" et l'autre "bbbb:",Réponse étrange en utilisant PCRE Regex

je PROGRAMMÉS:

char *src = "aaa: bbbb:"; 
char *pattern = "a(.*?):|b(.*?):"; 
pcre *re = NULL; 

//---missing out--- 

re = pcre_compile(pattern, // pattern, 
        0,   // options, 
        &error,  // errptr, 
        &erroffset, // erroffset, 
        NULL);  // tableptr, 
while (
     (rc = pcre_exec(re,  // regex ptr, 
       NULL,   // extra arg, 
       src,   // subject, 
       strlen(src), // length, 
       0,    // startoffset, 
       0,    // options, 
       ovector,  // ovector, 
       OVECCOUNT)  // ovecsize, 
    )!=PCRE_ERROR_NOMATCH) 
    { 
     printf("\nOK, string has matched ...there are %d matchups\n\n",rc); // 
     for (i = 0; i < rc; i++) 
     { 
      char *substring_start = src + ovector[2*i]; 
      int substring_length = ovector[2*i+1] - ovector[2*i]; 
      printf("$%2d: %.*s length: %d\n", i, substring_length, substring_start,substring_length); 
     } 
     src = src + ovector[1]; // to move the src pointer to the end offset of current matchup 
     if (!src) break; 
    } 
pcre_free(re); 

Je suis mon résultat:

Source : aaa: bbbb: 
Pattern: "a(.*?):|b(.*?):" 

OK, string has matched ...there are 2 matches 

$ 0: aaa: length: 4 
$ 1: aa length: 2 

OK, string has matched ...there are 3 matches 

$ 0: bbbb: length: 5 
$ 1: length: 0 
$ 2: bbb length: 3 

Et je me demande, comment ai-je la réponse "$ 1: longueur: 0"?

// -------------------------------------------- --------------------------------------------

@Jonathan Leffler Je pense que ta réponse est juste.

En ce moment j'ai essayé

Source: "aaa: bbb: ccc:" 
Pattern: "c(.+?):|a(.+?):|b(.+?):" 

et a obtenu le résultat se présente comme suit:

$ 0: aaa: length: 4 
$ 1: length: 0 
$ 2: aa length: 2 

$ 0: bbbb: length: 5 
$ 1: length: 0 
$ 2: length: 0 
$ 3: bbb length: 3 

$ 0: cccc: length: 5 
$ 1: ccc length: 3 

qui prouve votre réponse dans le sens inverse:

La capture de l'expression régulière arrête quand un match est trouvé, donc aaa: a été capturé avec a(.+?): après avoir essayé match c(.+?):, et la première ligne du résultat montre la chaîne entière , Le n ° 2 montre le résultat de décalage correspondant avec l'alternative c(.+?):

B (. +?), Il fut capturé enfin dans l'expression rationnelle, qui explique les deux length : 0

Pour c (. +?), il a été capturé en premier lieu, donc il n'y a pas length : 0

+0

Pourriez-vous augmenter l'exemple de source afin qu'il compile? – thuovila

+0

Peut-être parce que vous utilisez '*' au lieu de '+' – jcubic

Répondre

1

Il y a deux captures dans la regex, une dans chaque alternative. Cependant, les captures sont numérotées de gauche à droite. Dans le second cas, la première capture ($1) est vide; il n'y avait pas a dans ce qu'il correspondait, donc la première capture est vide; la seconde capture ($2) contient les b que vous attendez. Il est presque plus surprenant qu'il n'y ait rien de spécifié pour la seconde capture lors de la première mise en correspondance.Je suppose que les captures sont vides s'il n'y avait pas de données pour eux.

+0

Merci! Je pense que votre réponse est correcte ~ –

0

Un * indique un nombre, y compris zéro, de caractères. Ce qui signifie qu'il ne correspond à "rien". Un caractère + devrait être utilisé à la place, ce qui indique "correspondre à au moins 1".

+0

Il ne répond pas à la question pourquoi il est là. – nhahtdh

+0

J'ai essayé un (. +?), Le résultat est allé pareil –

0

Essayez d'utiliser le modèle char *pattern = "a+?:|b+?:";

EDIT Remarqué qui vient "a+:|b+:" travaillera également.

+1

La question demande pourquoi cela se produit, pas de suggestion sur l'expression régulière, qui est probablement un exemple pour montrer l'étrangeté. – nhahtdh

0

Le motif:

a(.*?): 

Ce modèle signifie rechercher un uncaptured « a », suivi de la capture d'une quantité de quoi que ce soit, modifié pour que le motif correspondant plus petit, suivi d'un uncaptured « : » .

Si vous considérez la chaîne:

aaa: 

pense maintenant à la dernière 'a' avant les deux points:

a: 

Il correspond au modèle - un 'a', suivi par rien, suivi d'un deux-points. Le 'rien' est capturé, c'est pourquoi vous obtenez un résultat de longueur nulle.

+0

La chaîne globale capturée par le second match est 'bbbb'; l'explication impliquant 'a:' n'est évidemment pas applicable. –

+0

Désolé, je n'ai pas donné un bon exemple concernant mon vrai problème, mais votre réponse ne peut pas expliquer pourquoi il y a un 'longueur: 0' dans le résultat de' aaa: ' –