2010-03-01 7 views
1

Quelqu'un peut-il me donner le programme exemple complet comment travailler avec GNU fonctions REGEX dans gcc C ou C++ (http://docs.freebsd.org/info/regex/regex.info.GNU_Regex_Functions.html), avec re_pattern_buffer, re_compile_fastmap?Travailler avec GNU fonctions REGEX en C ou C++

Par exemple, traduire ce petit programme Python:

import re 
unlucky = re.compile('1\d*?3') 

nums = ("13", "31", "777", "10003") 

for n in nums: 
    if unlucky.search(n) is None: 
     print "lucky" 
    else: 
     print "unlucky" 

Merci!

+0

Vous devriez essayer de le traduire vous-même. Si vous éprouvez des difficultés à le faire fonctionner, n'hésitez pas à poser des questions spécifiques. –

Répondre

3

Ok, avant d'entrer dans le code, je devrais mentionner que vous voudrez peut-être utiliser une bibliothèque de plus haut niveau. Vous avez dit C++, ce qui vous ouvre à Boost.Regex et autres. Même si vous voulez rester avec C, il y a de meilleures options. Je trouve le POSIX functions un peu plus propre, pour ne pas mentionner plus portable.

// Tell GNU to define the non-standard APIs 
#define _GNU_SOURCE 
// This is actually the same header used for the POSIX API. 
// Except then you obviously don't need _GNU_SOURCE 
#include <regex.h> 
#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    struct re_pattern_buffer pat_buff; // Put a re_pattern_buffer on the stack 
    // The next 4 fields must be set. 

    // If non-zero, applies a translation function to characters before 
    // attempting match (http://www.delorie.com/gnu/docs/regex/regex_51.html) 
    pat_buff.translate = 0; 
    // If non-zero, optimization technique. Don't know details. 
    // See http://www.delorie.com/gnu/docs/regex/regex_45.html 
    pat_buff.fastmap = 0; 
    // Next two must be set to 0 to request library allocate memory 
    pat_buff.buffer = 0; 
    pat_buff.allocated = 0; 
    char pat_str[] = "1[^3]*3"; 
    // This is a global (!) used to set the regex type (note POSIX APIs don't use global for this) 
    re_syntax_options = RE_SYNTAX_EGREP; 
    // Compile the pattern into our buffer 
    re_compile_pattern(pat_str, sizeof(pat_str) - 1, &pat_buff); 
    char* nums[] = {"13", "31", "777", "10003"}; // Array of char-strings 
    for(int i = 0; i < sizeof(nums)/sizeof(char*); i++) 
    { 
     int match_ret; 
     // Returns number of characters matches (may be 0, but if so there's still a match) 
     if((match_ret = re_match(&pat_buff, nums[i], strlen(nums[i]), 0, NULL)) >= 0) 
     { 
      printf("unlucky\n"); 
     } 
     else if(match_ret == -1) // No match 
     { 
      printf("lucky\n"); 
     } 
     // Anything else (though docs say -2) is internal library error 
     else 
    { 
      perror("re_match"); 
     } 
    } 
    regfree(&pat_buff); 
} 

EDIT: J'ai ajouté plus d'explications sur les champs obligatoires, et le regfree. J'ai eu le chanceux/malchanceux en arrière avant, ce qui explique une partie de la divergence. L'autre partie est que je ne pense pas que les syntaxes regex disponibles ici supportent les opérateurs paresseux (*?). Dans ce cas, il existe un correctif simple, utilisant "1[^3]*3".

+0

Merci! Mais la sortie devrait être "malchanceux chanceux chanceux malchanceux", alors que j'ai eu "chanceux malchanceux malchanceux malchanceux". Aussi pourriez-vous commenter sur 'pat_buff.translate = 0; pat_buff.fastmap = 0; pat_buff.buffer = 0; pat_buff.allocated = 0; 'part? Et aussi à propos de 'regfree()'? Quand avons-nous besoin de l'utiliser? –

+0

Quant à Boost.Regex je ne peux pas l'utiliser car le programme fonctionnera dans un environnement spécifique où Boost n'est pas disponible. La portabilité n'est pas non plus un problème - le programme doit compiler uniquement sur une version spécifique de gcc. –

+0

Merci! Ça fonctionne maintenant. Je pense aussi que, au lieu de 're_syntax_options' global, nous pouvons utiliser la fonction' re_set_syntax() '. –