23.1. Универсализация произвольных строк
В главе 14 мы говорили о том, как с помощью функции glob() производится универсализация имен файлов, однако пользователи, знакомые с возможностями универсализации, нередко пытаются применить их и к другим разновидностям строк. Функция fnmatch() позволяет применять правила универсализации в отношении произвольных строк:
#include <fnmatch.h>
int fnmatch(const char * pattern, const char * string, int flags);
Предложенный шаблон является стандартным выражением универсализации с четырьмя специальными символами, за которые отвечает аргумент flags.
| * | Соответствует любой строке, включая пустую. | 
| ? | Соответствует любому одиночному символу. | 
| [ | Начинает список символов для сопоставления или, если следующим символом является ^, то список символов для несовпадения. Весь список может совпадать, или не совпадать с одним символом. Список заканчивается знаком]. | 
|  | Следующий символ будет интерпретироваться как литерал, а не как специальный символ. | 
На результаты универсализации влияет аргумент 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 <regex.h>
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);

 
                