Разработка приложений в среде 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, которая предлагает возможности поиска регулярного выражения в текстовых
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);
Поделиться:
Популярные книги
Белые погоны
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Черный дембель. Часть 1
1. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Лишняя дочь
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Темный Лекарь 5
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Последний из рода Демидовых
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Чиновникъ Особых поручений
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Попаданка в академии драконов 4
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Боги, пиво и дурак. Том 6
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Курсант: Назад в СССР 10
10. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сделай это со мной снова
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Болотник 2
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Камень Книга двенадцатая
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Небо для Беса
3. Самбисты
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Надуй щеки! Том 4
4. Чеболь за партой
Фантастика:
попаданцы
уся
дорама
5.00