2013-11-27 16 views
6

C'è un modo per usare un'espressione regolare non greedy in C come si può usare in Perl? Ho provato diverse cose, ma in realtà non funziona.Espressione regolare Posix non-golosa

Attualmente sto usando questa espressione regolare che corrisponde a un indirizzo IP e la corrispondente richiesta HTTP, ma è avido, anche se sto usando il * ?:

([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1

In questo esempio, corrisponde sempre l'intera stringa:

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

int main() { 

    int a, i; 
    regex_t re; 
    regmatch_t pm; 
    char *mpages = "TEST 127.0.0.1 GET /test.php HTTP/1.1\" 404 525 \"-\" \"Mozilla/5.0 (Windows NT HTTP/1.1 TEST"; 

    a = regcomp(&re, "([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1", REG_EXTENDED); 

    if(a!=0) 
     printf(" -> Error: Invalid Regex"); 

    a = regexec(&re, &mpages[0], 1, &pm, REG_EXTENDED); 

    if(a==0) { 

     for(i = pm.rm_so; i < pm.rm_eo; i++) 
      printf("%c", mpages[i]); 
     printf("\n"); 
    } 
    return 0; 
} 

$ ./regtest

127.0.0.1 GET /test.php HTTP/1.1" 404 525 "-" "Mozilla/5.0 (Windows NT HTTP/1.1

+1

Puoi aggiungere la stringa di input alla domanda. [Sembra funzionare per me.] (Http://regexr.com?37cvn) – OGHaza

+1

Non so 'c' quindi non posso consigliare, ma il problema è nel tuo codice [non la tua regex] (http: //regexr.com?37cvt). Se aggiungi altro alla fine della stringa di input, probabilmente diventerà evidente che non corrisponde al secondo 'HTTP/1.1', ma piuttosto che restituisce l'intera stringa di input. – OGHaza

+0

È possibile utilizzare una corrispondenza IP più accurata. Controlla questa risposta: http://stackoverflow.com/a/106223/363573 – Stephan

risposta

5

No, non ci sono quantificatori non grezzi nelle espressioni regolari POSIX. Ma esiste una libreria che fornisce espressioni regolari perl per C: http://www.pcre.org/

0

Come ho detto in precedenza in un commento, utilizzare grep -E per eseguire test con regex POSIX, in questo modo verrà migliorato il tempo di sviluppo. Ad ogni modo, sembra che il tuo problema sia con l'espressione regolare piuttosto che con la caratteristica mancante.

Non sono abbastanza chiaro di cosa si vuole ottenere dalla richiesta ... supponendo che si desideri solo l'indirizzo IP, il verbo HTTP e la risorsa, si potrebbe finire con la seguente espressione regolare.

regcomp(&re, "\\b(.?[0-9])+\\s+(GET|POST|PUT)\\s+([^ ]+)", REG_EXTENDED); 

Essere consapevoli del fatto che diverse ipotesi sono state fatte. Ad esempio, questa regex presuppone che l'indirizzo IP sia ben formato, ma assume anche una richiesta con un verbo HTTP GET, POST, PUT. Modifica in base alle tue esigenze.

0

Il metodo di forza bruta di ottenere una regex per abbinare fino alla successiva occorrenza di una parola è:

"([^H]|H[^T]|HT[^T]|HTT[^P]|HTTP{^/]|HTTP/[^1]|HTTP/1[^.]|HTTP/1\\.[^1])*HTTP/1\\.1" 

a meno che non si può ottenere più intelligenti sulla tua partita - il quale è possibile: HTTP requests sono

e nessuno dei non terminali sulla destra corrisponde agli spazi incorporati. Quindi:

"[0-9]{1,3}(\\.[0-9]{1,3}){3} [^ ]* [^ ]* HTTP/1\\.1" 

in quanto si sta assegnando solo lo spazio per la partita intera espressione, o mettere le parentesi di nuovo dentro per ottenere pezzi.

-1

Nel codice, pm deve essere un array di regmatch_t e nel tuo caso dovrebbe avere almeno 2-4 elementi, a seconda delle sottoespressioni() che desideri acquisire.

Hai un solo elemento. Il primo elemento, pm[0], ottiene sempre qualunque testo corrisponda all'intera RE. Questo è quello che otterrai. È pm[1] che otterrà il testo della sotto-espressione first() (l'indirizzo IP) e pm[3] che otterrà il testo corrispondente al termine (.*?).

Ma anche così, come affermato sopra (da Wumbley, W. Q.) la libreria regex POSIX potrebbe non supportare quantificatori non avidi.

0
a = regcomp(&re, "([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1", REG_EXTENDED|REG_ENHANCED); 

non ha questa macro nel vecchio tempo

#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 \ 
|| __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 
#define REG_ENHANCED 0400 /* Additional (non-POSIX) features */ 
#endif