Компиляция / Сопоставление регулярных выражений POSIX в C
Вопрос
Я пытаюсь сопоставить следующие элементы в строке pcode
:
u
за которым следует 1 или 2-значный номерphaseu
phasep
x
(в окружении символов, не содержащих слов)y
(в окружении символов, не содержащих слов)z
(в окружении символов, не содержащих слов)
Я попытался реализовать совпадение регулярных выражений с помощью функций регулярных выражений POSIX (показано ниже), но возникли две проблемы:
- Скомпилированный шаблон, похоже, не имеет подшаблонов (т.е.скомпилированный.n_sub == 0).
- Шаблон не находит совпадений в строке "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:]]+)";