Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

23.2.1. Регулярные выражения в Linux

Существуют две разновидности регулярных выражений: базовые регулярные выражения (basic regular expression — BRE) и расширенные регулярные выражения (extended regular expression — ERE). Они соответствуют (в первом приближении) командам grep и egrep. Описание каждой разновидности регулярных выражений можно найти на man-странице grep, в стандарте POSIX.2 (IEEE, 1993), в [32], а также в других источниках, поэтому здесь мы не станем описывать их синтаксис, а рассмотрим только интерфейс функции, с помощью которой вы сможете применять регулярные выражения в своих программах.

23.2.2. Сопоставление с регулярными выражениями

Стандарт 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);

void regfree(regex_t *preg);

size_t regerror(int errcode, const regex_t *preg, char * errbuf,

 size_t errbuf_size);

Прежде чем сравнивать строку с регулярным выражением, нужно выполнить ее компиляцию с помощью функции

regcomp
. Аргумент
regex_t *preg
указывает на область хранения регулярного выражения. Чтобы каждое регулярное выражение было доступно одновременно, для него потребуется отдельный аргумент
regex_t
. Структура
regex_t
включает только один важный член,
re_nsub
, который определяет количество подвыражений в регулярном выражении, заключенных в скобки. Рассмотрим оставшуюся часть непрозрачной структуры.

Аргумент

сflags
определяет варианты интерпретации регулярного выражения
regex
. Он может иметь нулевое значение или быть любой комбинацией перечисленных ниже значений, объединенных битовым "ИЛИ".

REG_EXTENDED
Вместо синтаксической структуры BRE будет использоваться структура ERE.
REG_ICASE
Не будет учитываться регистр.
REG_NOSUB
Не будут выделяться подстроки. Функция
regexec
будет игнорировать аргументы
nmatch
и
pmatch
.
REG_NEWLINE
Если значение
REG_NEWLINE
не будет задано, то символ новой строки будет обрабатываться точно так же, как и любой другой символ. Символы
^
и
$
соответствуют только началу и концу всей строки, а не соседним символам новой строки. Если значение
REG_NEWLINE
будет задано, то результат будет таким же, как и в случае использования
grep
,
sed
и других стандартных системных инструментальных средств; символ ^ осуществляет привязку к началу строки и символу, следующему после символа новой строки (фактически он соответствует строке нулевой длины, следующей за символом новой строки);
$
осуществляет привязку к концу строки и символу, следующему после символа новой строки (фактически, он соответствует строке нулевой длины, предшествующей символу новой строки); символ
.
не соответствует символу новой строки.

Ниже представлен пример типичного вызова функции.

if ((rerr = regcomp(&p, "(^(.*[^\\])#.*$)|(^[^#]+$)",

 REG_EXTENDED|REG_NEWLINE))) {

 if (rerr == REG_NOMATCH) {

/* строка просто не совпадает с регулярным выражением */

 } else {

/* какая-то другая ошибка, например, неправильно сформированное регулярное выражение */

 }

}

Данное расширенное регулярное выражение находит строки в файле, которые не включены в комментарии, или которые, по крайней мере, частично, заключены в комментарии посредством символов

#
без префикса
\
. Эту разновидность регулярного выражения удобно использовать в качестве простого анализатора синтаксиса для конфигурационного файла какого-нибудь приложения.

Даже если вы компилируете выражение, которое, по вашему мнению, является нормальным, вам все равно необходимо проверить его на наличие ошибок. Функция

regcomp
возвращает нулевое значение при успешном выполнении компиляции и ненулевой код ошибки — в противном случае. Большинство ошибок может быть связано с разного рода ошибками в регулярных выражениях, но не исключено, что ошибка может быть связана с переполнением памяти. Далее в этой главе дается описание функции
regerror
.

#include <regex.h>

int regexec(const regex_t *preg, const chat *string, size_t nmatch,

 regmatch_t pmatch[], int eflags);

Функция

regexec
сравнивает строку с предварительно компилированным регулярным выражением. Аргумент
eflags
может иметь нулевое значение или быть любой комбинацией перечисленных ниже значений, объединенных битовым "ИЛИ".

REG_NOTBOL
Первый символ строки не будет соответствовать символу
^
. Любой символ, следующий за символом новой строки, будет соответствовать при том условии, что в вызове функции
regcomp
будет задано значение
REG_NEWLINE
.
REG_NOTEOL
Последний символ строки не будет соответствовать символу
$
. Любой символ, предшествующий символу новой строки, будет соответствовать символу
$
при том условии, что в вызове функции
regcomp
будет задано значение
REG_NEWLINE
.

Массив структур

regmatch_t
используется для представления местоположения подвыражений в регулярном выражении.

#include <regex.h>

typedef struct {

 regoff_t rm_so; /* индекс байта в строке в начале сопоставления*/

 regoff_t rm_eo; /* индекс байта в строке в конце сопоставления*/

} regmatch_t;

Первый элемент

regmatch_t
описывает всю совпавшую строку; обратите внимание, что вся эта строка содержит любой символ начала строки, включая хвостовой символ новой строки, независимо от того, задано ли значение
REG_NEWLINE
.

  • Читать дальше
  • 1
  • ...
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: