• Когда в
cflags
включен
REG_NEWLINE
, то:
• Символ конца строки не соответствует '
.
' или дополненному списку символов.
• Оператор
^
всегда соответствует положению непосредственно за вставленным символом конца строки независимо от установки
REG_BOL
.
• Оператор
$
всегда соответствует положению непосредственно перед вставленным символом конца строки независимо от установки
REG_EOL
.
Когда вы осуществляете построчный ввод/вывод, как в случае с
grep
, можно не включать
REG_NEWLINE
в
cflags
. Если в буфере несколько строк, и каждую из них нужно рассматривать как отдельную, с сопоставлением
^
и
$
, тогда следует включить
REG_NEWLINE
.
Структура
regex_t
по большей части непрозрачна. Код уровня пользователя может исследовать лишь один член этой структуры; остальное предназначено для внутреннего использования процедурами регулярных выражений:
typedef struct {
/* ...здесь внутренний материал... */
size_t re_nsub;
/* ...здесь внутренний материал... */
} regex_t;
В структуре
regmatch_t
есть по крайней мере два члена для использования кодом уровня пользователя:
typedef struct {
/* ...здесь возможный внутренний материал... */
regoff_t rm_so; /* Смещение начала вложенной строки в байтах */
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
| Цифра в ' \<i>цифра</i> ' недействительна |
REG_NOMATCH
| Строка не соответствует шаблону |