Linux программирование в примерах
echo~arnold/.p*12.8. Регулярные выражения
Регулярные выражения являются способом описания текстовых шаблонов для сопоставления. Если вы вообще сколько-нибудь использовали GNU/Linux или Unix, вы без сомнения знакомы с регулярными выражениями: они являются фундаментальной частью инструментария программиста Unix. Они неотъемлемы от таких повседневных программ, как
,grep,egrep,sed, Perl, а также редакторыawk,ed,viи Emacs. Если вы вообще не знакомы с регулярными выражениями, мы рекомендуем ознакомиться с некоторыми из книг или URL, указанных в разделе 12.9 «Рекомендуемая литература».vimPOSIX определяет два вида регулярных выражений: базовый и расширенный. Программы типа
,grepи строчный редакторsedиспользуют базовые регулярные выражения. Программы типаedиegrepиспользуют расширенные регулярные выражения. Следующие функции дают вам возможность использовать в своих программах любой вид.awk#include <sys/types.h> /* POSIX */#include <regex.h>int regcomp(regex_t *preg, const char *regex, int cflags);int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags);size_t regerror(int errcode, const regex_t *preg,char *errbuf, size_t errbuf_size);void regfree(regex_t *preg);Чтобы сопоставить регулярное выражение, нужно сначала откомпилировать строчную версию регулярного выражения. Компиляция преобразует регулярное выражение во внутренний формат. Затем откомпилированная форма исполняется для строки для проверки, совпадает ли она с первоначальным регулярным выражением. Функции следующие.
int regcomp(regex_t *preg, const char *regex, int cflags)Компилирует регулярное выражение
во внутреннее представление, сохраняя его в структуреregex, на которую указываетregex_t.pregконтролирует процесс компиляции; ее значение равно 0 или побитовому ИЛИ одного или более флагов из табл. 12.7cflagsint regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags)Выполняет откомпилированное регулярное выражение в
в строке*pregконтролирует способ выполнения; ее значение равно 0 или побитовому ИЛИ одного или более флагов из табл. 12.8. Вскоре мы обсудим другие аргументы.string eflagssize_t regerror(int errcode, const regex_t *preg,char *errbuf, size_t errbuf_size)Преобразует ошибку, возвращенную
илиregcomp(), в удобочитаемую строку.regexec()void regfree(regex_t *preg)Освобождает динамическую память, используемую откомпилированным регулярным выражением в
.*pregЗаголовочный файл
определяет ряд флагов. Некоторые используются с<regex.h>; другие используются сregcomp(). Однако, все они начинаются с префикса 'regexec()'. В табл. 12.7 перечислены флаги для компиляции регулярных выражений с помощьюREG_.regcomp()Таблица 12.7. Флаги для
regcomp()
Константа Значение REG_EXTENDEDИспользовать расширенные регулярные выражения. По умолчанию используются базовые регулярные выражения REG_ICASEСопоставление игнорирует регистр символовregexec()REG_NEWLINEОператоры, заменяющие любой символ, не включают символ конца строки REG_NOSUBИнформация о начале и конце вложенною шаблона не требуется (см текст) Флаги для сопоставления регулярных выражений с помощью
приведены в табл. 12.8.regexec()Таблица 12.8. Флаги дли
regexec()
Константа Значение REG_NOTBOLОператор ^ (начало строки) не сопоставляется REG_NOTEOLОператор $ (конец строки) не сопоставляется Флаги
,REG_NEWLINEиREG_NOTBOLвзаимодействуют друг с другом. Это немного запутано, поэтому мы будем продвигаться небольшими шажками.REG_NOTEOL• Когда в
не включенcflags, символ конца строки действует в качестве обычного символа. С ним может быть сопоставлен метасимвол 'REG_NEWLINE' (любой символ), а также дополненные списки символов ('.'). При этом[^...]не сопоставляется немедленно с началом вставленного символа новой строки, а$не сопоставляется немедленно с его концом.^• Когда в
установленeflags, операторREG_NOTBOLне соответствует началу строки. Это полезно, когда параметр^является адресом символа в середине сопоставляемого текста.string• Сходным образом, когда в
установленeflags, операторREG_NOTEOLне соответствует концу строки.$