Компиляция / сопоставление регулярных выражений POSIX в C - PullRequest
3 голосов
/ 23 июня 2009

Я пытаюсь сопоставить следующие элементы в строке pcode:

  • u с последующим 1 или 2-значным числом
  • phaseu
  • phasep
  • x (в окружении несловесных символов)
  • y (в окружении несловесных символов)
  • z (в окружении несловесных символов)

Я пытался реализовать сопоставление регулярных выражений с помощью функций регулярных выражений POSIX (показано ниже), но у меня есть две проблемы:

  1. Кажется, что скомпилированный шаблон не имеет подшаблонов (т.е. compiled.n_sub == 0).
  2. Шаблон не находит совпадений в строке "u0", что ему и правда нужно!

Я уверен, что сама строка регулярных выражений работает - в том смысле, что она работает в python и TextMate - моя проблема заключается в компиляции и т. Д. В C. Любая помощь в получении этой работы будет высоко оценена.

Заранее спасибо за ваши ответы.

if(idata=tb_find(deftb,pdata)){
    MESSAGE("Global variable!\n");
    char pattern[80] = "((u[0-9]{1,2})|(phaseu)|(phasep)|[\\W]+([xyz])[\\W]+)";
    MESSAGE("Pattern = \"%s\"\n",pattern);
    regex_t compiled;
    if(regcomp(&compiled, pattern, 0) == 0){
        MESSAGE("Compiled regular expression \"%s\".\n", pattern);
    }

    int nsub = compiled.re_nsub;
    MESSAGE("nsub = %d.\n",nsub);
    regmatch_t matchptr[nsub];
    int err;
    if(err = regexec (&compiled, pcode, nsub, matchptr, 0)){
        if(err == REG_NOMATCH){
            MESSAGE("Regular expression did not match.\n");
        }else if(err == REG_ESPACE){
            MESSAGE("Ran out of memory.\n");
        }
    }
    regfree(&compiled);
}

1 Ответ

14 голосов
/ 23 июня 2009

Кажется, вы намереваетесь использовать нечто, похожее на «расширенный» синтаксис POSIX regex. POSIX определяет два различных синтаксиса регулярных выражений: «базовый» (читай «устаревший») синтаксис и «расширенный» синтаксис. Чтобы использовать расширенный синтаксис, необходимо добавить флаг REG_EXTENDED для regcomp:

...
if(regcomp(&compiled, pattern, REG_EXTENDED) == 0){
...

Без этого флага regcomp будет использовать «базовый» синтаксис регулярных выражений. Есть несколько важных отличий, таких как:

  • Нет поддержки оператора |
  • Скобки для субматчей должны быть экранированы, \( и \)

Следует также отметить, что расширенный синтаксис регулярных выражений POSIX не совместим 1: 1 с регулярными выражениями Python (не знаю о TextMate) В частности, я боюсь, что эта часть вашего регулярного выражения не работает в POSIX или, по крайней мере, не переносима:

 [\\W]

POSIX способ указать непробельные символы:

 [^[:space:]]

Все ваши регулярные выражения для POSIX должны выглядеть следующим образом в C:

 char *pattern = "((u[0-9]{1,2})|(phaseu)|(phasep)|[^[:space:]]+([xyz])[^[:space:]]+)";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...