Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

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

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
.

Следующие элементы массива хранят подвыражения, заключенные в скобки, в том порядке, в котором они присутствуют в регулярном выражении, в порядке расположения открывающих скобок. (В коде на языке С элемент

i
эквивалентен выражению замены
\i
в программах
sed
или
awk
.) В несовпадающих подвыражениях член
regmatch_t.rm_so
имеет значение
– 1
.

В следующем коде производится сопоставление строки с регулярным выражением, содержащим подвыражения. После сопоставления на экран выводятся все совпавшие подвыражения.

 1: /* match.с */

 2:

 3: #include <alloca.h>

 4: #include <sys/types.h>

 5: #include <regex.h>

 6: #include <stdlib.h>

 7: #include <string.h>

 8: #include <stdio.h>

 9:

10: void do_regerror(int errcode, const regex_t *preg) {

11: char *errbuf;

12: size_t errbuf_size;

13:

14: errbuf_size = regerror(errcode, preg, NULL, 0);

15: errbuf = alloca(errbuf_size);

16: if (!errbuf) {

17: perror("alloca");

18: return;

19: }

20:

21: regerror(errcode, preg, errbuf, errbuf_size);

22: fprintf(stderr, "%s\n", errbuf);

23: }

24:

25: int main {

26:

27: regex_t p;

28: regmatch_t *pmatch;

29: int rerr;

30: char *regex = "(^(.*[^\\])#.*$)|(^[^#]+$)";

31: char string[BUFSIZ+1];

32: int i;

33:

34: if ((rerr = regcomp(&p, regex, REG_EXTENDED | REG_NEWLINE))) {

35: do_regerror(rerr, &p);

36: }

37:

38: pmatch = alloca(sizeof(regmatch_t) * (p.re_nsub+1));

39: if (!pmatch) {

40: perror("alloca");

41: }

42:

43: printf("Введите строку: ");

44: fgets(string, sizeof(string), stdin);

45:

46: if ((rerr = regexec(&p, string, p.re_nsub+1, pmatch, 0))) {

47: if (rerr == REG_NOMATCH) {

48: /* эту ситуацию может обработать regerror,

49: * но зачастую она обрабатывается особым образом

50: */

51: printf("Строка не совпадает с %s\n", regex);

52: } else {

53: do_regerror(rerr, &p);

54: }

55: } else {

56: /* сопоставление закончено */

57: printf("Строка совпадает с регулярным выражением %s\n", regex);

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

Сын Тишайшего

Яманов Александр
1. Царь Федя
Фантастика:
попаданцы
альтернативная история
фэнтези
5.20
рейтинг книги
Сын Тишайшего

"Искажающие реальность" Компиляция. Книги 1-14

Атаманов Михаил Александрович
Искажающие реальность
Фантастика:
боевая фантастика
космическая фантастика
киберпанк
рпг
5.00
рейтинг книги
Искажающие реальность Компиляция. Книги 1-14

Школа. Первый пояс

Игнатов Михаил Павлович
2. Путь
Фантастика:
фэнтези
7.67
рейтинг книги
Школа. Первый пояс

Невеста на откуп

Белецкая Наталья
2. Невеста на откуп
Фантастика:
фэнтези
5.83
рейтинг книги
Невеста на откуп

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Вперед в прошлое!

Ратманов Денис
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое!

Аргумент барона Бронина 4

Ковальчук Олег Валентинович
4. Аргумент барона Бронина
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Аргумент барона Бронина 4

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Измена. Право на обман

Арская Арина
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Право на обман

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Жаба с кошельком

Донцова Дарья
19. Любительница частного сыска Даша Васильева
Детективы:
иронические детективы
8.26
рейтинг книги
Жаба с кошельком

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Академия чаросвет. Тень

Ярошинская Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Академия чаросвет. Тень

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4