Могу ли я использовать regex_t для нескольких компиляций - PullRequest
0 голосов
/ 22 сентября 2009

Основной вопрос, не понятный мне для человека из regcomp.

Если у меня есть статический экземпляр regex_t, могу ли я использовать его для нескольких компиляций, не каждый раз освобождая его, что-то вроде:

    int match(char* pattern, char* name) {
       static regex_t re;
       regcomp(&re,pattern,REG_EXTENDED|REG_NOSUB);
      ...
    }

Сам код немного сложнее, и идея состоит в том, чтобы использовать статическую переменную для сохранения компиляции, если шаблон не был изменен между вызовами. Вопрос в том, нужно ли мне вызывать regfree перед каждым новым regcomp.

Спасибо.

Ответы [ 2 ]

1 голос
/ 22 сентября 2009

Если вы хотите использовать предыдущий результат regcomp(), который был скомпилирован в re, это прекрасно, если вы не звоните regfree() в это время.

Но если вы хотите скомпилировать новое регулярное выражение, снова вызвав regcomp(), вам нужно вызвать regfree(), чтобы правильно высвободить все ресурсы, использованные предыдущим вызовом regcomp(). Так что вам, вероятно, понадобится какая-то другая статическая переменная, которая отслеживает, использовалась ли переменная re при вызове regcomp() и должна ли она быть regfree() -ed перед повторным использованием.

Что-то вроде:

int match(char* pattern, char* name) {
   static regex_t re;
   static int re_in_use = 0;

   if (isNewRegex( pattern)) {  // however you want to determine this...
        if (re_in_use) {
            regfree( &re);
            re_in_use = 0;
        }
   }

   re_in_use = regcomp(&re,pattern,REG_EXTENDED|REG_NOSUB);

  ...
}
0 голосов
/ 22 сентября 2009

Извините, я не могу написать хорошее объяснение, но вот пример кода для одноэлементного кэша regcomp ():

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <regex.h> 

static struct {
  char *pattern;
  regex_t re;
} last_match = { .pattern = (char*)NULL };


int match( const char *pattern, const char *name ){
  int ret;

  if( last_match.pattern != (char*)NULL  &&  strcmp( last_match.pattern, pattern ) != 0 ){
    free( last_match.pattern ); last_match.pattern = (char*)NULL;
    regfree( &last_match.re );
  }

  if( last_match.pattern == (char*)NULL ){
    last_match.pattern = (char*)malloc( strlen(pattern)+1 );
    strcpy( last_match.pattern, pattern );
    ret = regcomp( &last_match.re, last_match.pattern, REG_EXTENDED|REG_NOSUB );
    printf("regcomp: %i  '%s'\n", ret, last_match.pattern );
  }

  ret = regexec( &last_match.re, name, 0, (regmatch_t*)NULL, 0);
  printf("regexec: %i\n", ret );

  return ret;
}

int main(void){
  match( "[0-9]+", "qwer1234" );
  match( "[0-9]+", "asdf5678" );

  match( "[a-z]+", "qwer1234" );
  match( "[a-z]+", "asdf5678" );
}

Если вы запустите код, вы увидите два сообщения 'regcomp' и четыре сообщения 'regexec' из-за повторного использования regex_t.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...