Проверял на glibc, gcc 13.3, Ubuntu 24.04. Все фрагменты ниже собраны в одну программу и скомпилированы с
-Wall -Wextra без единого предупреждения.Скомпилировать шаблон
regex_t re;
int rc = regcomp(&re, "^([a-z]+)=([0-9]+)$",
REG_EXTENDED);
REG_EXTENDED включает ERE: скобки и + работают без обратных слешей. Без флага получите BRE, где группа пишется как \(...\).Понять, почему не скомпилировалось
char err[256];
if (rc != 0) {
regerror(rc, &re, err, sizeof err);
fprintf(stderr, "regcomp: %s\n", err);
}
Буфер обязан быть массивом. На незакрытой скобке
[a-z получите Unmatched [, [^, [:, [., or [=. Нюанс: regfree вызывайте только после успешного regcomp, для неудачной компиляции освобождать нечего.Сопоставить и достать группы
regmatch_t m[3];
const char *s = "app=100";
if (regexec(&re, s, 3, m, 0) == 0)
printf("%.*s\n", (int)(m[1].rm_eo - m[1].rm_so),
s + m[1].rm_so);
m[0] — всё совпадение, m[1] и дальше — группы по порядку. На app=100 вышло app в первой группе и 100 во второй. Нюанс: смещения в байтах, не в символах. В строке ключ=42 вторая группа начинается с байта 9, хотя символов перед ней пять. И если компилировали с REG_NOSUB, массив m не заполняется вовсе.Не забыть освободить
regfree(&re);
Замерил: 100 тысяч компиляций в цикле без
regfree раздули процесс до 1.4 ГБ, с ним — 1.8 МБ. В демоне, который компилирует шаблон на каждый запрос, это вопрос часов.Где POSIX молчит вместо ошибки
Самое неприятное не в том, чего API не умеет, а в том, как он об этом сообщает:
\d+ на "abc 123" -> No match
<.*?> на "<a><b>" -> <a><b>
(?<=x)y -> Invalid preceding regular expression
Просмотры и именованные группы падают на компиляции — это честно. А вот
\d компилируется и тихо ничего не находит, вместо него нужен [0-9]. И .*? не ошибка, а просто жадный .*: вернул всю строку вместо <a>. Привычки из PCRE здесь ломают логику молча.А вы в C-утилитах держитесь
<regex.h> или сразу тянете PCRE2?#Linux #C #POSIX #regex #DevOps