2009-09-14 14 views
5

C kullanmayla deneyimsizim ve eşleşmeleri almak için PCRE kullanmam gerekiyor.
İşte benim kaynak kodunun bir örnektir: Bu tanıtımdaTüm eşleşme gruplarını almak için PCRE'yi nasıl kullanabilirim?

int test2() 
{ 
    const char *error; 
    int erroffset; 
    pcre *re; 
    int rc; 
    int i; 
    int ovector[OVECCOUNT]; 

    char *regex = "From:([^@]+)@([^\r]+)"; 
    char str[] = "From:[email protected]\r\n"\ 
        "From:[email protected]\r\n"\ 
        "From:785[email protected]\r\n"; 

    re = pcre_compile (
      regex,  /* the pattern */ 
      0,     /* default options */ 
      &error,    /* for error message */ 
      &erroffset,   /* for error offset */ 
      0);     /* use default character tables */ 

    if (!re) { 
     printf("pcre_compile failed (offset: %d), %s\n", erroffset, error); 
     return -1; 
    } 

    rc = pcre_exec (
     re,     /* the compiled pattern */ 
     0,     /* no extra data - pattern was not studied */ 
     str,     /* the string to match */ 
     strlen(str),   /* the length of the string */ 
     0,     /* start at offset 0 in the subject */ 
     0,     /* default options */ 
     ovector,    /* output vector for substring information */ 
     OVECCOUNT);   /* number of elements in the output vector */ 

    if (rc < 0) { 
     switch (rc) { 
      case PCRE_ERROR_NOMATCH: 
       printf("String didn't match"); 
       break; 

      default: 
       printf("Error while matching: %d\n", rc); 
       break; 
     } 
     free(re); 
     return -1; 
    } 

    for (i = 0; i < rc; i++) { 
     printf("%2d: %.*s\n", i, ovector[2*i+1] - ovector[2*i], str + ovector[2*i]); 
    } 
} 

, çıktı sadece:

0: From:[email protected]
1: regular.expressions
2: example.com

Ben çıkışına hepsini istiyorum maçlar; bunu nasıl yapabilirim?

+0

Düzenli bir ifade kullanmayın, ancak gerçek ayrıştırıcı. Posta protokolü sadece düz posta kutusu adresinden daha fazlasını sağlar. – Gumbo

+0

Bu pcre için bir demo, sadece eşleşen gruplar halinde pcre kullanmayı bilmek istiyorum. Yorumunuz için teşekkürler. – tbmvp

+0

Bu gönderiye başvurabilirsiniz: http://stackoverflow.com/questions/7785557/pcre-match-all-groups-in-c – soulmachine

cevap

6

Bunu kolaylaştırmak için PCRE'yi sarmak için bir sınıf kullanıyorum, ancak pcre_exec'ten sonra ovektör, orijinal dizedeki eşleşmeleri bulmak için gereken alt dizgi dizinlerini içerir.

Yani olurdu gibi bir şey:

#include <string> 
#include <iostream> 
#include "pcre.h" 

int main (int argc, char *argv[]) 
{ 
    const char *error; 
    int erroffset; 
    pcre *re; 
    int rc; 
    int i; 
    int ovector[100]; 

    char *regex = "From:([^@]+)@([^\r]+)"; 
    char str[] = "From:[email protected]\r\n"\ 
        "From:[email protected]\r\n"\ 
        "From:[email protected]\r\n"; 

    re = pcre_compile (regex,   /* the pattern */ 
         PCRE_MULTILINE, 
         &error,   /* for error message */ 
         &erroffset,  /* for error offset */ 
         0);    /* use default character tables */ 
    if (!re) 
    { 
     printf("pcre_compile failed (offset: %d), %s\n", erroffset, error); 
     return -1; 
    } 

    unsigned int offset = 0; 
    unsigned int len = strlen(str); 
    while (offset < len && (rc = pcre_exec(re, 0, str, len, offset, 0, ovector, sizeof(ovector))) >= 0) 
    { 
     for(int i = 0; i < rc; ++i) 
     { 
      printf("%2d: %.*s\n", i, ovector[2*i+1] - ovector[2*i], str + ovector[2*i]); 
     } 
     offset = ovector[1]; 
    } 
    return 1; 
} 
+0

Cevabınız için teşekkür ederiz. Ama hala tüm maçları nasıl çıkaracağımı bilmiyorum. – tbmvp

+0

Sadece ilk gruptan mı geliyorsunuz? Regex'i derlerken PCRE_MULTILINE seçeneğini belirtmeniz gerekir. Detaylar için http://www.pcre.org/pcre.txt adresine bakınız. Örneği güncelleyeceğim. –

+0

Gereksinim duyduğum şeyi yapmak için cevabımdaki kodu güncelledim. Kuşkusuz PCRE uzmanı değilim, çünkü sadece bir sarıcı ile kullandım, bu yüzden bu karmaşıklıklara aşina değilim. Bunu icra için 1 çağrı ile yapmanın bir yolu olacağını düşünürdüm. ve ovector dizisini dize dizinleriyle tüm eşleşmelere döndürmesini sağlayın. Bu olsa da hile yapmalı. –

5

not: pcre_exec son parametresi() olmalıdır eleman-sayımı, sizeof değil (!) (http://www.pcre.org/readme.txt)

+1

Ayrıca: öğe sayısı 3'ün katları (ör., 90 değil 100!) – glob

+0

http://regexkit.sourceforge.net/Documentation/pcre/pcre_exec.html – glob

İlgili konular