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

на главную

Жанры

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

Троан Эрик В.

Шрифт:

58: for (i = 0; i <= p.re_nsub; i++) {

59: /* вывод на экран совпавшей части (частей) строки */

60: if (pmatch[i].rm_so != -1) {

61: char *submatch;

62: size_t matchlen = pmatch[i].rm_eo - pmatch[i].rm_so;

63: submatch = malloc(matchlen+1);

64: strncpy(submatch, string+pmatch[i].rm_so,

65: matchlen);

66: submatch[matchlen] = '\0';

67: printf("совпавшее подвыражение %d: %s\n", i,

68: submatch);

69: free(submatch);

70: } else {

71: printf ("нет
совпадения с подвыражением %d\n", i);

72: }

73: }

74: }

75: exit(0);

76: }

В примере регулярного выражения из программы

match.с
имеется три подвыражения. Первое из них представляет собой всю строку, содержащую текст, за которым следует символ комментария, вторым является текст в строке, предшествующей символу комментария, а третье представляет всю строку без символа комментария. Для строки, в начале которой содержится комментарий, элементу
rm_so
во втором и третьем элементе из массива
pmatch[]
присвоено значение
– 1
. Для строки, в начале которой содержится комментарий, значение
– 1
присваивается первому и второму элементу; для строки, не содержащей символы комментария, второму и третьему элементу присваивается значение
– 1
.

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

regfree
, но не
free
:

#include <regex.h>

void regfree(regex_t *preg);

В стандарте POSIX четко не сказано, следует ли использовать функцию

regfree
каждый раз при вызове функции
regcomp
, или же только после того, как вы в последний раз вызывали функцию
regcomp
в одной структуре
regex_t
. Таким образом, чтобы избежать утечек памяти, в промежутках между использованием структур
regex_t
необходимо вызывать функцию
regfree
.

Всякий раз когда функция

regcomp
или
regex
возвращает ненулевой результат, функция
regerror
может предоставить подробное сообщение, в котором будет указано, в чем состоит ошибка. Она записывает по возможности все сообщение об ошибке в буфер и возвращает размер всего сообщения. Поскольку вы заранее не знаете, какой размер будет иметь сообщение, то сначала вам необходимо узнать его размер, а затем распределить и использовать буфер, как показано в следующем далее примере кода. Поскольку этот вариант обработки ошибок быстро становится устаревшим, и вам придется включать его как минимум дважды (один раз после функции
regcomp
и один раз после функции
regex
), мы советуем вам написать код собственной оболочки функции
regerror
, как показано в строке 10 из листинга
math.с
.

23.2.3. Простая утилита

grep

grep
является популярной утилитой, определенной в стандарте POSIX, которая предлагает возможности поиска регулярного выражения в текстовых
файлах. Ниже показана простая (не соответствующая стандарту POSIX) версия утилиты
grep
, реализованная с помощью функций стандартного регулярного выражения.

1: /* grep.с */

2:

3: #include <alloca.h>

4: #include <ctype.h>

5: #include <popt.h>

6: #include <regex.h>

7: #include <stdio.h>

8: #include <string.h>

9: #include <unistd.h>

 10:

 11: #define MODE_REGEXP 1

 12: #define MODE_EXTENDED 2

 13: #define MODE_FIXED 3

 14:

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

 16: char *errbuf;

 17: size_t errbuf_size;

 18:

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

 20: errbuf = alloca(errbuf_size);

 21: if (!errbuf) {

 22: perror("alloca");

 23: return;

 24: }

 25:

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

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

 28: }

 29:

 30: int scanFile(FILE * f, int mode, const void * pattern,

 31: int ignoreCase, const char * fileName,

 32: int * maxCountPtr) {

 33: long lineLength;

 34: char * line;

 35: int match;

 36: int rc;

 37: char * chptr;

 38: char * prefix = "";

 39:

 40: if (fileName) {

 41: prefix = alloca(strlen(fileName) + 4);

 42: sprintf(prefix, "%s: ", fileName);

 43: }

 44:

 45: lineLength = sysconf(_SC_LINE_MAX);

 46: line = alloca(lineLength);

 47:

 48: while (fgets(line, lineLength, f) && (*maxCountPtr)) {

 49: /* если у нас не будет завершающего символа '\n'

 50: то мы не сможем получить всю строку целиком */

 51: if (line [strlen (line) -1] != '\n') {

 52: fprintf(stderr, " %s line слишком длинная\n", prefix);

 53: return 1;

 54: }

 55:

 56: if (mode == MODE_FIXED) {

 57: if (ignoreCase) {

 58: for (chptr = line; *chptr; chptr++) {

 59: if (isalpha(*chptr)) *chptr = tolower(*chptr);

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

Лорд Системы 8

Токсик Саша
8. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 8

Осознание. Пятый пояс

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

Академия

Кондакова Анна
2. Клан Волка
Фантастика:
боевая фантастика
5.40
рейтинг книги
Академия

Князь Мещерский

Дроздов Анатолий Федорович
3. Зауряд-врач
Фантастика:
альтернативная история
8.35
рейтинг книги
Князь Мещерский

Огненный князь 5

Машуков Тимур
5. Багряный восход
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Огненный князь 5

Новый Рал 4

Северный Лис
4. Рал!
Фантастика:
попаданцы
5.00
рейтинг книги
Новый Рал 4

Варлорд

Астахов Евгений Евгеньевич
3. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Варлорд

Пропала, или Как влюбить в себя жену

Юнина Наталья
2. Исцели меня
Любовные романы:
современные любовные романы
6.70
рейтинг книги
Пропала, или Как влюбить в себя жену

Инкарнатор

Прокофьев Роман Юрьевич
1. Стеллар
Фантастика:
боевая фантастика
рпг
7.30
рейтинг книги
Инкарнатор

Жена на пробу, или Хозяйка проклятого замка

Васина Илана
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Жена на пробу, или Хозяйка проклятого замка

Холодный ветер перемен

Иванов Дмитрий
7. Девяностые
Фантастика:
попаданцы
альтернативная история
6.80
рейтинг книги
Холодный ветер перемен

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия

Приручитель женщин-монстров. Том 5

Дорничев Дмитрий
5. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 5

Довлатов. Сонный лекарь

Голд Джон
1. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь