На результаты универсализации влияет аргумент flags
, и здесь он будет полезен, прежде всего, для универсализации имен файлов. Если вы не будете осуществлять универсализацию имен файлов, то вам, скорее всего, нужно будет присвоить аргументу flags
значение 0
.
FNM_NOESCAPE | Обработка символа \ как обычного, а не специального символа. |
FNM_PATHNAME | Символы / в строке string не сопоставляются с последовательностью * , ? , или даже [/] в шаблоне pattern ; сопоставление производится только с литералом, а не специальным символом / . |
FNM_NOESCAPE | Первый символ . в шаблоне pattern соответствует символу . в строке string только в том случае, если он является первым символом в строке string или если задано значение FNM_PATHNAME , а символ . в string непосредственно следует за символом \ . |
Функция fnmatch()
возвращает нулевое значение, если шаблон соответствует строке, FNM_NOMATCH
, если шаблон не соответствует строке, или другое неопределенное значение в случае возникновения ошибки.
Пример использования функции fnmatch()
вы можете посмотреть в программе, приведенной в разделе 14.7.3 главы 14, в которой эта функция используется как часть простой реализации команды find
.
23.2. Регулярные выражения
Регулярные выражения, используемые в программах sed
, awk
, grep
, vi
, а также во множестве других программ Unix, со временем приобрели большое значение в среде программирования Unix. Регулярные выражения можно применять и при написании программ на языке С. В этом разделе будет рассказано об их использовании и будет предложен пример простой программы синтаксического анализа файла, построенной на этих функциях.
23.2.1. Регулярные выражения в Linux
Существуют две разновидности регулярных выражений: базовые регулярные выражения (basic regular expression — BRE) и расширенные регулярные выражения (extended regular expression — ERE). Они соответствуют (в первом приближении) командам grep и egrep. Описание каждой разновидности регулярных выражений можно найти на man-странице grep, в стандарте POSIX.2 (IEEE, 1993), в [32], а также в других источниках, поэтому здесь мы не станем описывать их синтаксис, а рассмотрим только интерфейс функции, с помощью которой вы сможете применять регулярные выражения в своих программах.
23.2.2. Сопоставление с регулярными выражениями
Стандарт POSIX определяет четыре функции обработки регулярных выражений.
#include
int regcomp(regex_t *preg, const char * regex, int cflags);
int regexec(const regex_t *preg, const char * string, size_t nmatch,
regmatch_t pmatch[], int eflags);
void regfree(regex_t *preg);
size_t regerror(int errcode, const regex_t *preg, char * errbuf,
size_t errbuf_size);
Прежде чем сравнивать строку с регулярным выражением, нужно выполнить ее компиляцию с помощью функции regcomp()
. Аргумент regex_t *preg
указывает на область хранения регулярного выражения. Чтобы каждое регулярное выражение было доступно одновременно, для него потребуется отдельный аргумент regex_t
. Структура regex_t
включает только один важный член, re_nsub
, который определяет количество подвыражений в регулярном выражении, заключенных в скобки. Рассмотрим оставшуюся часть непрозрачной структуры.
Аргумент сflags
определяет варианты интерпретации регулярного выражения regex
. Он может иметь нулевое значение или быть любой комбинацией перечисленных ниже значений, объединенных битовым "ИЛИ".