обеспечивает почти все возможности регулярных выражений, тогда как его
программировать значительно проще, чем в исходном общем случае.
Начнем с самой функции, осуществляющей проверку на соответствие. Ее задача —
определить, соответствует ли строка текста регулярному выражению:
/* match: ищет regexp в text */
int match(char *regexp, char *text) {
if (regexp[0] == '",'')
return matchhere(regexp+1, text);
do { /* должны попробовать,
даже если строка пуста */ if (matchhere(regexp, text))
return 1;
} while (*text++ != '\0'); return 0; }
Если регулярное выражение начинается с ",
то текст должен начинаться с символов,
соответствующих остальной части выражения. При другом начале мы проходим по
тексту, используя matchhere для выяснения, соответствует ли текст каждой позиции
выражения. Как только мы находим соответствие, миссия наша завершена.
Обратите внимание на использование do-while: выражениям может соответствовать
пустая строка (например, шаблону $ соответствует пустая строка, а шаблону . * —
любое
количество символов, включая и ноль), поэтому вызвать matchhere мы
должны даже в том случае, если строка текста пуста.
Большая часть работы выполняется в рекурсивной функции matchhere:
/* matchhere: ищет regexp в начале text */
int matchhere(char *regexp, char *text)
{
if (regexp[0] == "\0')
return 1; if (regexp[1] == '*')
return matchstar(regexp[0], regexp+2, text); if
(regexp[0] == '$' && regexp[1] == 'ДО')
return *text == '\О'; if (*text!='\0' &&
(regexp[0]==',' || regexp[0]==*text))
return matchhere(regexp+1, text+1); return 0; }
Если регулярное выражение пусто, это означает, что мы дошли до его конца и,
следовательно, нашли соответствие. Если
выражение оканчивается символом $, оно
имеет соответствие только в том случае, если текст также расположен в конце. Если
выражение начинается с точки, то первый символ соответствующего текста может
быть любым. В противном случае выражение начинается с какого-то обычного
символа, который) в тексте соответствует только самому себе. Символы ~ и $,
встречающиеся в
середине регулярного выражения, рассматриваются как простые
литеральные, а не метасимволы.
Отметьте, что matchhe re, убедившись в совпадении одного символа из; шаблона и
подстроки, вызывает себя самое, таким образом, глубина ре] курсии может быть
такой же, как и длина шаблона (при полном соответветствии).
Единственный сложный случай представляет собой выражение, начинающееся с
символа и звездочки
, например х*. В этом случае мы осуществляем вызов matchstar,
где первым аргументом является операнд звездочки (то есть х), а следующими
аргументами — шаблон после звездочки и сам текст.