2009-10-27 13 views
14

Minęło 10 lat, odkąd spojrzałem na c. Muszę napisać mały program w c, który analizuje ciąg znaków. Chciałem używać wyrażeń regularnych, ponieważ używam ich od lat, ale nie mam pojęcia, jak to zrobić w c. Spędziłem ranek Googling i nie mogę znaleźć żadnych prostych przykładów (np. Użyj tej biblioteki, to jest metodologia). Czy ktoś może dać mi prosty przykład?c Wyrażenie regularne howto

Dzięki!

Odpowiedz

38

Można użyć PCRE:

Biblioteka PCRE to zestaw funkcji, które wdrażają wzorca wyrażenia regularnego pasujące stosując tę ​​samą składnię i semantykę jak Perl 5. PCRE posiada własną natywne API, a także zestaw funkcji opakowania, które odpowiadają API wyrażeń regularnych POSIX. Biblioteka PCRE jest darmowa, nawet do budowania komercyjnego oprogramowania.

Zobacz przykład pcredemo.c dla przykładu PCRE.

Jeśli nie możesz korzystać z PCRE, pomoc prawdopodobnie jest dostępna w Twoim systemie (as @tinkertim pointed out). W przypadku systemu Windows można użyć numeru gnuwin Regex for Windows package.

Dokumentacja regcomp zawiera następujący przykład:

#include <regex.h> 

/* 
* Match string against the extended regular expression in 
* pattern, treating errors as no match. 
* 
* Return 1 for match, 0 for no match. 
*/ 

int 
match(const char *string, char *pattern) 
{ 
    int status; 
    regex_t re; 

    if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) { 
     return(0);  /* Report error. */ 
    } 
    status = regexec(&re, string, (size_t) 0, NULL, 0); 
    regfree(&re); 
    if (status != 0) { 
     return(0);  /* Report error. */ 
    } 
    return(1); 
} 
+0

+1, choć POSIX istnieje, pcre jest dostępny na prawie wszystkich nowoczesnych systemach. –

+0

Dzięki! Daje mi dobry punkt wyjścia. – jeffkolez

+0

To jest dobra, przydatna i wspólna odpowiedź. Mam nadzieję, że to pytanie otrzyma więcej głosów, ponieważ regex w C może być trudny w zależności od platformy. –

0

Inną opcją oprócz rodzimej biblioteki C jest użycie interfejsu na inny język jak Python lub Perl. Brak konieczności radzenia sobie z obsługą ciągów C, a lepsza obsługa języków dla regexów powinna znacznie ułatwić ci pracę. Można również użyć narzędzia jak SWIG wygenerować owijarki do wywoływania kodu z C

+0

Łuskanie do innego programu nigdy nie powinno być dobrym pomysłem, chyba że jest to absolutnie jedyny sposób na wykonanie zadania. –

+0

@NathanAdams nic w tej odpowiedzi nie dotyczy wysyłania do innego programu. – hobbs

6

Jeśli zmuszony do POSIX tylko (no pcre), oto smakołyk upadku z powrotem:

#include <regex.h> 
#include <stdbool.h> 

bool reg_matches(const char *str, const char *pattern) 
{ 
    regex_t re; 
    int ret; 

    if (regcomp(&re, pattern, REG_EXTENDED) != 0) 
     return false; 

    ret = regexec(&re, str, (size_t) 0, NULL, 0); 
    regfree(&re); 

    if (ret == 0) 
     return true; 

    return false; 
} 

Można to nazwać tak:

int main(void) 
{ 
    static const char *pattern = "/foo/[0-9]+$"; 

    /* Going to return 1 always, since pattern wants the last part of the 
    * path to be an unsigned integer */ 
    if (! reg_matches("/foo/abc", pattern)) 
     return 1; 

    return 0; 
} 

I wysoce zalecamy wykorzystanie PCRE jeśli jego dostępny. Ale miło jest to sprawdzić i trochę się wycofać.

Wyciągnąłem fragmenty z projektu aktualnie w moim edytorze. Jest to bardzo prosty przykład, ale daje ci typy i funkcje do wyszukiwania, jeśli ich potrzebujesz. Ta odpowiedź w mniejszym lub większym stopniu wzmacnia odpowiedź Sinana.

+0

Dzięki - ładne przykłady.Nie mam jeszcze pewności co do środowiska, więc warto mieć kopię zapasową na wypadek, gdyby PCRE nie było dostępne. – jeffkolez

+1

@jeffkolez Powodzenia w projekcie. 10 lat, odkąd dotknąłeś C ... a tu jesteś w jednym z jego mrocznych zakamarków. Jeśli zdecydujesz się na strzelanie do komputera, rozważ najpierw zakupienie pistoletu NERF. –

0

Powinieneś również zajrzeć do biblioteki regex. Używa wyrażeń regularnych, takich jak te, które można zapisać w powłoce systemu Linux.

Aby uzyskać więcej informacji, pod Linuksem, typ „człowiek regcomp” bez cudzysłowów

+0

Nie dodaje to żadnych nowych informacji do tego, co jest już dostępne w innych odpowiedziach. –