PCRE

Поделись знанием:
Перейти к: навигация, поиск
PCRE
Тип

Библиотека регулярных выражений

Написана на

C

Операционная система

кроссплатформенная

Последняя версия

8.37_4 (Wed Aug 26 2015)

Лицензия

BSD

Сайт

[pcre.org g]

К:Википедия:Статьи без изображений (тип: не указан)

PCRE (Perl Compatible Regular Expressions) — библиотека, реализующая работу регулярных выражений в стиле Perl (с некоторыми отличиями). Синтаксис регулярных выражений PCRE значительно более мощный и гибкий, чем стандартных регулярных выражений POSIX.

В том или ином виде доступна для очень многих языков программирования. В частности, в PHP модуль PCRE включен в ядро.

Автор библиотеки — Филип Хейзел (Philip Hazel). Библиотека написана на Си и распространяется под свободной лицензией BSD.





Функции библиотеки

Базовые функции

pcre *pcre_compile(const char *pattern, int options,
          const char **errptr, int *erroffset, 
          const unsigned char *tableptr);

Функция pcre_compile компилирует регулярное выражение во внутреннее представление библиотеки. Первый аргумент — ссылка на содержащую регулярное выражение строку. Во втором можно указать различные атрибуты (соответствующие опциям /igms… в Perl). Последний аргумент — ссылка на таблицу кодировки, созданную pcre_maketables. Если при компиляции шаблона произошла ошибка, возвращает NULL.

int pcre_exec(const pcre *code, const pcre_extra *extra, 
          const char *subject, int length, int startoffset, int options, 
          int *ovector, int ovecsize);

Функцию pcre_exec используют для поиска совпадений. В первом аргументе передают значение, возвращённое pcre_compile. Во втором — дополнительные сведения, возвращённые функцией pcre_study. Следующие три аргумента — анализируемая строка, её длина и смещение, начиная с которого будет обрабатываться строка. Затем — параметр, указывающий опции (их подробное описание см. в документации).

В последних двух аргументах нужно указать ссылку на зарезервированный массив целых чисел и его длину. В этот массив заносятся пары индексов, указывающих на начало и конец совпадений. Первые два элемента массива описывают положение всего совпавшего выражения. Остальные пары — положение подстрок, которые совпали с выражениями в круглых скобках в шаблоне (аналоги переменных вида $1 в Perl).

pcre_extra *pcre_study(const pcre *code, int options, const char **errptr);

Функция ускоряет работу программы, выполняющей множество сопоставлений с одним и тем же шаблоном. Создаёт переменную, которая хранит дополнительные сведения о шаблоне, ускоряющие его обработку функцией pcre_exec

const unsigned char *pcre_maketables(void);

Создает таблицу символов для использования её функцией pcre_compile

Извлечение подстрок

int pcre_copy_substring(const char *subject, int *ovector, int stringcount, 
        int stringnumber, char *buffer, int buffersize);
int pcre_get_substring(const char *subject, int *ovector,
        int stringcount, int stringnumber, const char **stringptr);

Получает из строки одну из найденных подстрок. Для этого указывается номер найденной подстроки. Эти функции отличаются друг от друга тем, что pcre_copy_substring записывает результат в буфер, которому уже выделена память, а pcre_get_substring выделяет память для буфера и записывает в него результат.

Первые четыре параметра у указанных функций одинаковые: первый — строка, в которой производился поиск, второй — массив, созданный функцией pcre_exec, третий — значение, возвращённое функцией pcre_exec, то есть количество найденных подстрок, четвёртый — номер нужной подстроки.

Функции возвращают длину подстроки в случае успеха, в противном случае — отрицательное значение — код ошибки

int pcre_get_substring_list(const char *subject, int *ovector,
        int stringcount, const char ***listptr);

Получает из строки все найденные подстроки.

void pcre_free_substring(const char *stringptr);
void pcre_free_substring_list(const char **stringptr);

Освобождают память, выделенную, соответственно, pcre_get_substring и pcre_get_substring_list.

POSIX-совместимые

В PCRE также реализованы функции работы с регулярными выражениями, совместимые со стандартом POSIX. Эти функции нельзя использовать для обработки строк в кодировке, отличающейся от базовой ASCII:

int regcomp(regex_t *preg, const char *pattern, int cflags);
int regexec(regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
void regfree(regex_t *preg);

Функция regerror преобразует код ошибки, возвращаемый функциями regcomp и regexec, в сообщение об ошибке. Первый параметр — код ошибки. Второй — скомпилированный шаблон. Третий — строка, в которую будет записано сообщение. Четвёртый — её максимальная длина.

Функция regfree освобождает переменную, хранящую скомпилированный шаблон, которая передаётся как параметр. Применяется, когда нужно использовать одну и ту же переменную для нескольких операциях поиска.

Компиляция Just-in-time

Эта опциональная возможность доступна в версии 8.20 и выше, если она была разрешена при сборке библиотеки PCRE. Наибольший прирост производительности возможен, например, когда вызывающая программа повторно использует ранее оттранслированные регулярные выражения. Поддержка JIT была написана Золтаном Херцегом (Zoltan Herczeg)[1] и не предназначена для интерфейсов POSIX и C++. Встроенный транслятор работает на следующих архитектурах:[1]

  • ARM v5, v7 и Thumb2
  • Intel x86 32-бита и 64-бита
  • MIPS 32-бита
  • Power PC 32-бита и 64-бита
  • SPARC 32-бит (экспериментально)
  • TileGX (экспериментально, начиная с 8.34)[2]

Пример использования

Это пример простейшей программы на С++. Регулярное выражение и строка заданы в исходном тексте (Компилировать с ключом -lpcre).

# include <iostream>
# include <string.h>
# include <pcre.h>

using namespace std;

int main() {

   char pattern[] = "[es]"; // шаблон (регулярное выражение)
   char str[] = "test";  // разбираемая строка

   // создание таблицы перекодировки для локали ru
   const unsigned char *tables = NULL;         
   setlocale (LC_CTYPE, (const char *) "ru.");
   tables = pcre_maketables();

   // компилирование регулярного выражения во внутреннее представление
   pcre *re;
   int options = 0;
   const char *error;
   int erroffset;
   re = pcre_compile ((char *) pattern, options, &error, &erroffset, NULL);

   if (!re) { // в случае ошибки компиляции
      cerr << "Failed at offset " << erroffset << ":" << error << "\n";
   } else {
      int count = 0;
      int ovector[30];

      count = pcre_exec (re, NULL, (char *) str, strlen(str), 0, 0, ovector, 30);
      // выполнение сопоставления с образцом
      if (!count) { // если нет совпадений
         cout << "No match\n";
      } else {
         //вывод пар {начало, конец} совпадения
         for (int c = 0; c < 2 * count; c += 2) {
            if (ovector[c] < 0) { // или <unset> для несопоставившихся подвыражений
               cout << "<unset>\n";
            } else{
               cout << ovector[c] << ovector[c + 1] << "\n";
            }
         }
      }
   }
   
   // освобождаем данные, под которые выделялась память
   pcre_free((void *) re);
   pcre_free((void *) tables);
   return 0;
}

Напишите отзыв о статье "PCRE"

Примечания

  1. 1 2 [www.pcre.org/pcre.txt PCRE(3) Library Functions Manual] (англ.).
  2. Jiong Wang (Tilera Corporation). [gitorious.org/pcre/pcre/commit/e1603e6c9a8425a4c3e7e7aab2f4255d76e756c3 Add JIT support for the 64 bit TileGX architecture.] (англ.) (14 October 2013). — Патч добавляющий JIT транслятор для архитектуры TileGX в библиотеку PCRE (более 12000 строк).

Ссылки

  • [pcre.org/ pcre.org] (англ.) — Домашняя страница PCRE.
  • [pcre.org/pcre.txt pcre.org/pcre.txt] (англ.) — Документация PCRE.
  • [libs.wikia.com/wiki/PCRE Русская вики-документация по PCRE (некоторые страницы не переведены)]
  • [www.pcre.ru Универсальная энциклопедия регулярных выражений стандарта PCRE]
  • [www.shtogrin.com/library/web/pcre/ www.shtogrin.com/library/web/pcre] — Perl-совместимые регулярные выражения (PCRE)
  • [myregexp.com/applet.html myregexp.com/applet.html] (англ.) — Online редактор регулярных выражений с полной подсветкой синтаксиса (PCRE) (java-applet)

Отрывок, характеризующий PCRE

– Нет, бг'ат, я сам с усам, – сказал Денисов, прочтя эти бумаги, и написал немцу, что, несмотря на душевное желание, которое он имел служить под начальством столь доблестного и знаменитого генерала, он должен лишить себя этого счастья, потому что уже поступил под начальство генерала поляка. Генералу же поляку он написал то же самое, уведомляя его, что он уже поступил под начальство немца.
Распорядившись таким образом, Денисов намеревался, без донесения о том высшим начальникам, вместе с Долоховым атаковать и взять этот транспорт своими небольшими силами. Транспорт шел 22 октября от деревни Микулиной к деревне Шамшевой. С левой стороны дороги от Микулина к Шамшеву шли большие леса, местами подходившие к самой дороге, местами отдалявшиеся от дороги на версту и больше. По этим то лесам целый день, то углубляясь в середину их, то выезжая на опушку, ехал с партией Денисов, не выпуская из виду двигавшихся французов. С утра, недалеко от Микулина, там, где лес близко подходил к дороге, казаки из партии Денисова захватили две ставшие в грязи французские фуры с кавалерийскими седлами и увезли их в лес. С тех пор и до самого вечера партия, не нападая, следила за движением французов. Надо было, не испугав их, дать спокойно дойти до Шамшева и тогда, соединившись с Долоховым, который должен был к вечеру приехать на совещание к караулке в лесу (в версте от Шамшева), на рассвете пасть с двух сторон как снег на голову и побить и забрать всех разом.
Позади, в двух верстах от Микулина, там, где лес подходил к самой дороге, было оставлено шесть казаков, которые должны были донести сейчас же, как только покажутся новые колонны французов.
Впереди Шамшева точно так же Долохов должен был исследовать дорогу, чтобы знать, на каком расстоянии есть еще другие французские войска. При транспорте предполагалось тысяча пятьсот человек. У Денисова было двести человек, у Долохова могло быть столько же. Но превосходство числа не останавливало Денисова. Одно только, что еще нужно было знать ему, это то, какие именно были эти войска; и для этой цели Денисову нужно было взять языка (то есть человека из неприятельской колонны). В утреннее нападение на фуры дело сделалось с такою поспешностью, что бывших при фурах французов всех перебили и захватили живым только мальчишку барабанщика, который был отсталый и ничего не мог сказать положительно о том, какие были войска в колонне.
Нападать другой раз Денисов считал опасным, чтобы не встревожить всю колонну, и потому он послал вперед в Шамшево бывшего при его партии мужика Тихона Щербатого – захватить, ежели можно, хоть одного из бывших там французских передовых квартиргеров.


Был осенний, теплый, дождливый день. Небо и горизонт были одного и того же цвета мутной воды. То падал как будто туман, то вдруг припускал косой, крупный дождь.
На породистой, худой, с подтянутыми боками лошади, в бурке и папахе, с которых струилась вода, ехал Денисов. Он, так же как и его лошадь, косившая голову и поджимавшая уши, морщился от косого дождя и озабоченно присматривался вперед. Исхудавшее и обросшее густой, короткой, черной бородой лицо его казалось сердито.
Рядом с Денисовым, также в бурке и папахе, на сытом, крупном донце ехал казачий эсаул – сотрудник Денисова.
Эсаул Ловайский – третий, также в бурке и папахе, был длинный, плоский, как доска, белолицый, белокурый человек, с узкими светлыми глазками и спокойно самодовольным выражением и в лице и в посадке. Хотя и нельзя было сказать, в чем состояла особенность лошади и седока, но при первом взгляде на эсаула и Денисова видно было, что Денисову и мокро и неловко, – что Денисов человек, который сел на лошадь; тогда как, глядя на эсаула, видно было, что ему так же удобно и покойно, как и всегда, и что он не человек, который сел на лошадь, а человек вместе с лошадью одно, увеличенное двойною силою, существо.
Немного впереди их шел насквозь промокший мужичок проводник, в сером кафтане и белом колпаке.
Немного сзади, на худой, тонкой киргизской лошаденке с огромным хвостом и гривой и с продранными в кровь губами, ехал молодой офицер в синей французской шинели.
Рядом с ним ехал гусар, везя за собой на крупе лошади мальчика в французском оборванном мундире и синем колпаке. Мальчик держался красными от холода руками за гусара, пошевеливал, стараясь согреть их, свои босые ноги, и, подняв брови, удивленно оглядывался вокруг себя. Это был взятый утром французский барабанщик.
Сзади, по три, по четыре, по узкой, раскиснувшей и изъезженной лесной дороге, тянулись гусары, потом казаки, кто в бурке, кто во французской шинели, кто в попоне, накинутой на голову. Лошади, и рыжие и гнедые, все казались вороными от струившегося с них дождя. Шеи лошадей казались странно тонкими от смокшихся грив. От лошадей поднимался пар. И одежды, и седла, и поводья – все было мокро, склизко и раскисло, так же как и земля, и опавшие листья, которыми была уложена дорога. Люди сидели нахохлившись, стараясь не шевелиться, чтобы отогревать ту воду, которая пролилась до тела, и не пропускать новую холодную, подтекавшую под сиденья, колени и за шеи. В середине вытянувшихся казаков две фуры на французских и подпряженных в седлах казачьих лошадях громыхали по пням и сучьям и бурчали по наполненным водою колеям дороги.
Лошадь Денисова, обходя лужу, которая была на дороге, потянулась в сторону и толканула его коленкой о дерево.
– Э, чег'т! – злобно вскрикнул Денисов и, оскаливая зубы, плетью раза три ударил лошадь, забрызгав себя и товарищей грязью. Денисов был не в духе: и от дождя и от голода (с утра никто ничего не ел), и главное оттого, что от Долохова до сих пор не было известий и посланный взять языка не возвращался.
«Едва ли выйдет другой такой случай, как нынче, напасть на транспорт. Одному нападать слишком рискованно, а отложить до другого дня – из под носа захватит добычу кто нибудь из больших партизанов», – думал Денисов, беспрестанно взглядывая вперед, думая увидать ожидаемого посланного от Долохова.
Выехав на просеку, по которой видно было далеко направо, Денисов остановился.
– Едет кто то, – сказал он.
Эсаул посмотрел по направлению, указываемому Денисовым.
– Едут двое – офицер и казак. Только не предположительно, чтобы был сам подполковник, – сказал эсаул, любивший употреблять неизвестные казакам слова.
Ехавшие, спустившись под гору, скрылись из вида и через несколько минут опять показались. Впереди усталым галопом, погоняя нагайкой, ехал офицер – растрепанный, насквозь промокший и с взбившимися выше колен панталонами. За ним, стоя на стременах, рысил казак. Офицер этот, очень молоденький мальчик, с широким румяным лицом и быстрыми, веселыми глазами, подскакал к Денисову и подал ему промокший конверт.
– От генерала, – сказал офицер, – извините, что не совсем сухо…
Денисов, нахмурившись, взял конверт и стал распечатывать.
– Вот говорили всё, что опасно, опасно, – сказал офицер, обращаясь к эсаулу, в то время как Денисов читал поданный ему конверт. – Впрочем, мы с Комаровым, – он указал на казака, – приготовились. У нас по два писто… А это что ж? – спросил он, увидав французского барабанщика, – пленный? Вы уже в сраженье были? Можно с ним поговорить?