2009-06-23 4 views
3

Я пытаюсь соответствовать следующие элементы в строке pcode:Компиляция/Matching POSIX регулярных выражений в C

  • 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); 
} 

ответ

14

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

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

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

  • Никакой поддержки | оператора
  • Кронштейны для submatches нужно не быть экранированы, \( и \)

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

[\\W] 

POSIX способ указать без пробелов является:

[^[:space:]] 

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

char *pattern = "((u[0-9]{1,2})|(phaseu)|(phasep)|[^[:space:]]+([xyz])[^[:space:]]+)"; 
+0

Спасибо Ville! Это было прекрасно. Можете ли вы сказать мне, есть ли эквивалент для OR (|), или я должен просто компилировать и сопоставлять несколько выражений? –

+0

Расширенный синтаксис POSIX поддерживает |. Я редактировал свой пост, чтобы включить регулярное выражение, которое должно делать то, что вам нужно (до тех пор, пока вы используете REG_EXTENDED). –

+0

Ты играешь! Ты спас меня от второго дня ругательства и колокольчика ... Очень ценится. –