Linux программирование в примерах
Шрифт:
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 /* ch12-grep.c - Простая версия grep, использующая функции POSIX */
2
3 #define _GNU_SOURCE 1 /* для getline)) */
4 #include <stdio.h>
5 #include <errno.h>
6 #include <regex.h>
7 #include <unistd.h>
8 #include <sys/types.h>
9
10 char *myname; /* для сообщений об ошибках */
11 int ignore_case = 0; /* опция -i: игнорировать регистр */
12 int extended = 0; /* опция -E: использовать расширенные регулярные выражения */
13 int errors = 0; /* число ошибок */
14
15 regex_t pattern; /* шаблон для поиска */
16
17 void compile_pattern(const char *pat);
18 void process(const char *name, FILE *fp);
19 void usage(void);
Строки 10–15 объявляют глобальные переменные программы. Первый набор (строки 10–13) для опций и сообщений об ошибках. Строка 15 объявляет
pattern
, в которой хранится откомпилированный шаблон. Строки 17–19 объявляют другие функции программы.
21 /* main --- обработка опций, открывание файлов */
22
23 int main(int argc, char **argv)
24 {
25 int с;
26 int i;
27 FILE *fp;
28
29 myname = argv[0];
30 while ((c = getopt(argc, argv, ":iE")) != -1) {
31 switch (c) {
32 case 'i':
33 ignore_case = 1;
34 break;
35 case 'E':
36 extended = 1;
37 break;
38 case '?':
39 usage;
40 break;
41 }
42 }
43
44 if (optind == argc) /* проверка исправности */
45 usage;
46
47 compile_pattern(argv[optind]); /* компилировать шаблон */
48 if (errors) /* ошибка компиляции */
49 return 1;
50 else
51 optind++;
Поделиться:
Популярные книги
Измена. Право на сына
4. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Возвышение Меркурия. Книга 7
7. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый
1. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
6.80
рейтинг книги
Идеальный мир для Социопата 12
12. Социопат
Фантастика:
фэнтези
постапокалипсис
рпг
7.00
рейтинг книги
Неудержимый. Книга XIII
13. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
АН (цикл 11 книг)
Аномальный наследник
Фантастика:
фэнтези
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Береги честь смолоду
1. Порог Хирург
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Сын Петра. Том 1. Бесенок
1. Сын Петра
Фантастика:
попаданцы
альтернативная история
6.80
рейтинг книги
Измена. Наследник для дракона
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Воин
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Сонный лекарь 7
7. Сонный лекарь
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Измена. Жизнь заново
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Мастер 2
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Темный Лекарь
1. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00