Регулярное выражение для строки с использованием библиотеки регулярных выражений GNU C - PullRequest
4 голосов
/ 04 февраля 2010

Я пишу регулярное выражение для использования с библиотекой регулярных выражений GNU C:

Строка имеет вид: (текст, выделенный курсивом - описание содержания)

(НЕ a #) start (возможно, пробел) : данные

Я написал следующий код, но он не будет совпадать.

regcomp(&start_state, "^[^#][ \\t]*\\(start\\)[ \\t]*[:].*$", REG_EXTENDED);

Что мне нужно написать?

примеры: соответствовать:

состояние: q0
состояние: q0
состояние: Q0S

не соответствует:

# состояние: q0
состояние q0
# состояние: q0

Спасибо!

Ответы [ 3 ]

7 голосов
/ 04 февраля 2010

Шаблон в вашем вопросе потреблял первую букву в state с [^#], из-за чего совпадение не могло быть продолжено, поскольку он пытается сопоставить tate с шаблоном \(state\).

Вы прошли флаг REG_EXTENDED, что означает, что вы не избегаете захвата скобок, но избегаете буквальных скобок.

С помощью регулярных выражений скажите, что вы делаете хотите сопоставить:

^[ \\t]*(state)[ \\t]*:.*$

как в

#include <stdio.h>
#include <regex.h>

int main(int argc, char **argv)
{
  struct {
    const char *input;
    int expect;
  } tests[] = {
    /* should match */
    { "state : q0", 1 },
    { "state: q0",  1 },
    { "state:q0s",  1 },

    /* should not match */
    { "#state :q0",  0 },
    { "state q0",    0 },
    { "# state :q0", 0 },
  };
  int i;
  regex_t start_state;
  const char *pattern = "^[ \\t]*(state)[ \\t]*:.*$";

  if (regcomp(&start_state, pattern, REG_EXTENDED)) {
    fprintf(stderr, "%s: bad pattern: '%s'\n", argv[0], pattern);
    return 1;
  }

  for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
    int status = regexec(&start_state, tests[i].input, 0, NULL, 0);

    printf("%s: %s (%s)\n", tests[i].input,
                            status == 0 ? "match" : "no match",
                            !status == !!tests[i].expect
                              ? "PASS" : "FAIL");
  }

  regfree(&start_state);

  return 0;
}

Выход:

state : q0: match (PASS)
state: q0: match (PASS)
state:q0s: match (PASS)
#state :q0: no match (PASS)
state q0: no match (PASS)
# state :q0: no match (PASS)
1 голос
/ 04 февраля 2010

Хорошо, я понял:

regcomp(&start_state, "^[^#]*[ \\t]*start[ \\t]*:.*$", REG_EXTENDED);

выше решает мою проблему! (оказывается, я забыл поставить * после [^ #]) ...

Спасибо за вашу помощь, Рубенс! :)

0 голосов
/ 04 февраля 2010

Это работает с вашими примерами данных:

^[^#]\s*\w+\s*:(?<data>.*?)$

РЕДАКТИРОВАТЬ : Я не знаю, но вам нужно включить поддержку многострочных сообщений, поскольку первые ^ и последние $ ведут себя по-разному с этим параметром.

...