Категории
Самые читаемые
PochitayKnigi » Компьютеры и Интернет » Программное обеспечение » Linux программирование в примерах - Арнольд Роббинс

Linux программирование в примерах - Арнольд Роббинс

Читать онлайн Linux программирование в примерах - Арнольд Роббинс

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 112 113 114 115 116 117 118 119 120 ... 165
Перейти на страницу:

size_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(). Однако, все они начинаются с префикса 'REG_'. В табл. 12.7 перечислены флаги для компиляции регулярных выражений с помощью regcomp().

Таблица 12.7. Флаги для regcomp()

Константа Значение REG_EXTENDED Использовать расширенные регулярные выражения. По умолчанию используются базовые регулярные выражения REG_ICASE Сопоставление regexec() игнорирует регистр символов REG_NEWLINE Операторы, заменяющие любой символ, не включают символ конца строки REG_NOSUB Информация о начале и конце вложенною шаблона не требуется (см текст)

Флаги для сопоставления регулярных выражений с помощью regexec() приведены в табл. 12.8.

Таблица 12.8. Флаги дли regexec()

Константа Значение REG_NOTBOL Оператор ^ (начало строки) не сопоставляется REG_NOTEOL Оператор $ (конец строки) не сопоставляется

Флаги REG_NEWLINE, REG_NOTBOL и REG_NOTEOL взаимодействуют друг с другом. Это немного запутано, поэтому мы будем продвигаться небольшими шажками.

• Когда в cflags не включен REG_NEWLINE, символ конца строки действует в качестве обычного символа. С ним может быть сопоставлен метасимвол '.' (любой символ), а также дополненные списки символов ('[^...]'). При этом $ не сопоставляется немедленно с началом вставленного символа новой строки, а ^ не сопоставляется немедленно с его концом.

• Когда в eflags установлен REG_NOTBOL, оператор ^ не соответствует началу строки. Это полезно, когда параметр string является адресом символа в середине сопоставляемого текста.

• Сходным образом, когда в eflags установлен REG_NOTEOL, оператор $ не соответствует концу строки.

• Когда в cflags включен REG_NEWLINE, то:

 • Символ конца строки не соответствует '.' или дополненному списку символов.

 • Оператор ^ всегда соответствует положению непосредственно за вставленным символом конца строки независимо от установки REG_BOL.

 • Оператор $ всегда соответствует положению непосредственно перед вставленным символом конца строки независимо от установки REG_EOL.

Когда вы осуществляете построчный ввод/вывод, как в случае с grep, можно не включать REG_NEWLINE в cflags. Если в буфере несколько строк, и каждую из них нужно рассматривать как отдельную, с сопоставлением ^ и $, тогда следует включить REG_NEWLINE.

Структура regex_t по большей части непрозрачна. Код уровня пользователя может исследовать лишь один член этой структуры; остальное предназначено для внутреннего использования процедурами регулярных выражений:

typedef struct {

 /* ...здесь внутренний материал... */

 size_t re_nsub;

 /* ...здесь внутренний материал... */

} regex_t;

В структуре regmatch_t есть по крайней мере два члена для использования кодом уровня пользователя:

typedef struct {

 /* ...здесь возможный внутренний материал... */

 regoff_t rm_so; /* Смещение начала вложенной строки в байтах */

 regoff_t rm_eo; /* Смещение первого байта после вложенной строки */

 /* ...здесь возможный внутренний материал... */

} regmatch_t;

Как поле re_nsub, так и структура regmatch_t предназначены для сопоставления вложенных выражений. Рассмотрим такое регулярное выражение:

[:пробел:]]+([[:цифра:]]+)[[:пробел:]]+([[:буква:]])+

Каждое из двух вложенных выражений в скобках могут соответствовать одному или более символам. Более того, текст, соответствующий каждому вложенному выражению, может начинаться и заканчиваться в произвольных участках строки.

regcomp() устанавливает в поле re_nsub число вложенных выражений в скобках внутри регулярного выражения, regexec() заполняет массив pmatch структур regmatch_t смещениями начальных и конечных байтов текста, соответствующих этим вложенным выражениям. Вместе эти данные позволяют заменять текст — удалять его или заменять другим текстом, точно так же, как в текстовом редакторе

pmatch[0] описывает часть строки, соответствующую всему регулярному выражению. Участок от pmatch[1] до pmatch[preg->re_nsub] описывает ту часть, которая соответствует каждому вложенному выражению в скобках. (Таким образом, вложенные выражения нумеруются начиная с 1.) Элементы rm_so и rm_eo не используемых элементов массива pmatch установлены в -1.

regexec() заполняет не более nmatch-1 элементов pmatch; поэтому следует убедиться, что имеется по крайней мере на 1 элемент больше, чем в preg->re_nsub.

Наконец, флаг REG_NOSUB для regcomp() означает, что начальная и завершающая информация не нужна. Этот флаг следует использовать, когда эти сведения не нужны; это потенциально может довольно значительно повысить производительность regexec().

Другими словами, если все, что вам нужно знать, это «соответствует ли?», включите REG_NOSUB. Однако, если нужно также знать, «где находится соответствующий текст?», этот флаг следует опустить.

В заключение, как regcomp(), так и regexec() возвращают 0, если они успешны, или определенный код ошибки, если нет. Коды ошибок перечислены в табл. 12.9.

Таблица 12.9. Коды ошибок regcomp() и regexec()

Константа Значение REG_BADBR Содержимое '{...}' недействительно. REG_BADPAT Регулярное выражение недействительно REG_BADRPT Символу ?, + или * не предшествует действительное регулярное выражение. REG_EBRACE Фигурные скобки ('{...}') не сбалансированы REG_EBRACK Квадратные скобки ('[...]') не сбалансированы REG_ECOLLATE В шаблоне использован недействительный элемент сортировки REG_ECTYPE В шаблоне использован недействительный класс символов REG_EESCAPE В шаблоне есть завершающий символ REG_EPAREN Группирующие скобки ('(...)' или '(...)') не сбалансированы REG_ERANGE Конечная точка в диапазоне не действительна REG_ESPACE Функции не хватило памяти REG_ESUBREG Цифра в 'цифра' недействительна REG_NOMATCH Строка не соответствует шаблону

Для демонстрации регулярных выражений ch12-grep.c предусматривает базовую реализацию стандартной программы grep, которая отыскивает соответствие шаблону. Наша версия использует по умолчанию базовые регулярные выражения. Для использования вместо этого расширенных регулярных выражений она принимает опцию -E, а для игнорирования регистра символов опцию -i. Как и настоящая grep, если в командной строке не указаны файлы, наша grep читает со стандартного ввода, а для обозначения стандартного ввода, как и в настоящей grep, может быть использовано имя файла '-'. (Эта методика полезна для поиска в стандартном вводе наряду с другими файлами.) Вот программа:

1 ... 112 113 114 115 116 117 118 119 120 ... 165
Перейти на страницу:
Тут вы можете бесплатно читать книгу Linux программирование в примерах - Арнольд Роббинс.
Комментарии