2010-04-05 13 views
19

Bir regex kullanarak başka bir dizeden ayıklamak çalışıyorum. desen gibi basit bir olalım ÖrneğinNormal ifadeli bir grubu nasıl yakalarsınız?

... I (... regcomp, regexec) POSIX regex fonksiyonlarını kullanıyorum ve ben bir grup yakalamada başarısız "MAIL FROM:<(.*)>"
(REG_EXTENDED CFLAGS ile)

Ben '>' '<' arasındaki her şeyi yakalamak istediğiniz ve

Sorunum regmatch_t bana bütün desen sınırlarını sağlamasıdır: parantez aramda sadece ne yerine (MAIL FROM ...> <) ...

Neyi eksik? peşin

sayesinde

düzenleme: Bazı kod

#define SENDER_REGEX "MAIL FROM:<(.*)>" 

int main(int ac, char **av) 
{ 
    regex_t regex; 
    int status; 
    regmatch_t pmatch[1]; 

    if (regcomp(&regex, SENDER_REGEX, REG_ICASE|REG_EXTENDED) != 0) 
    printf("regcomp error\n"); 
    status = regexec(&regex, av[1], 1, pmatch, 0); 
    regfree(&regex); 
    if (!status) 
     printf( "matched from %d (%c) to %d (%c)\n" 
      , pmatch[0].rm_so 
      , av[1][pmatch[0].rm_so] 
      , pmatch[0].rm_eo 
      , av[1][pmatch[0].rm_eo] 
      ); 

    return (0); 
} 

çıkışlar:

$./a.out "MAIL FROM:<abcd>$" 
matched from 6 (M) to 22 ($) 

çözüm:

RarrRarrRarr bahsedilen olarak, endeks pmatch[1].rm_so gerçekten de vardır ve bu nedenle regmatch_t pmatch[1];pmatch[1].rm_eo
regmatch_t pmatch[2];
ve regexec(&regex, av[1], 1, pmatch, 0);regexec(&regex, av[1], 2, pmatch, 0);

sayesinde :)

cevap

9

regmatch_t yapılar arasında pmatch dizisinin 0. elemanı içerir hale gelir Fark ettiğiniz gibi tüm dizginin sınırları eşleşti. Örneğinizde, dize eşleşmeleriyle ilgili alt-tanıma hakkında bilgi almak için, dizin 0'da değil, dizin 1'deki regmatch_t ile ilgileniyorsunuz.

Daha fazla yardıma gereksinim duyarsanız, sorunuzu gerçek bir küçük kod örneği içerecek şekilde düzenlemeyi deneyin; böylece kullanıcılar sorunu daha kolay bir şekilde tespit edebilir.

+0

Teşekkürler, bu sorun oldu :) – Sylvain

16

Birden çok grubu yakalamayı gösteren bir kod örneği.

Bu grubun '0' grubunun tamamını görebilirsiniz ve sonraki gruplar parantez içindeki bölümlerdir.

Bunun yalnızca kaynak dizesindeki ilk eşleşmeyi yakalayacağını unutmayın. Here's a version that captures multiple groups in multiple matches.

#include <stdio.h> 
#include <string.h> 
#include <regex.h> 

int main() 
{ 
    char * source = "___ abc123def ___ ghi456 ___"; 
    char * regexString = "[a-z]*([0-9]+)([a-z]*)"; 
    size_t maxGroups = 3; 

    regex_t regexCompiled; 
    regmatch_t groupArray[maxGroups]; 

    if (regcomp(&regexCompiled, regexString, REG_EXTENDED)) 
    { 
     printf("Could not compile regular expression.\n"); 
     return 1; 
    }; 

    if (regexec(&regexCompiled, source, maxGroups, groupArray, 0) == 0) 
    { 
     unsigned int g = 0; 
     for (g = 0; g < maxGroups; g++) 
     { 
      if (groupArray[g].rm_so == (size_t)-1) 
      break; // No more groups 

      char sourceCopy[strlen(source) + 1]; 
      strcpy(sourceCopy, source); 
      sourceCopy[groupArray[g].rm_eo] = 0; 
      printf("Group %u: [%2u-%2u]: %s\n", 
       g, groupArray[g].rm_so, groupArray[g].rm_eo, 
       sourceCopy + groupArray[g].rm_so); 
     } 
    } 

    regfree(&regexCompiled); 

    return 0; 
} 

Çıktı:

Group 0: [ 4-13]: abc123def 
Group 1: [ 7-10]: 123 
Group 2: [10-13]: def 
İlgili konular