Компиляция / Сопоставление регулярных выражений POSIX в C

StackOverflow https://stackoverflow.com/questions/1032068

  •  06-07-2019
  •  | 
  •  

Вопрос

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

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

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

  1. Скомпилированный шаблон, похоже, не имеет подшаблонов (т.е.скомпилированный.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);
}
Это было полезно?

Решение

Похоже, вы намерены использовать что-то похожее на "расширенный" синтаксис регулярных выражений POSIX.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:]]+)";
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top