The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Регулярные выражения в C++: Использование библиотеки PCRE. (pcre gcc cpp regex)


<< Предыдущая ИНДЕКС Правка src / Печать Следующая >>
Ключевые слова: pcre, gcc, cpp, regex,  (найти похожие документы)
From: webcode.ru <mail@webcode.ru.> Date: Sun, 24 Nov 2006 17:02:14 +0000 (UTC) Subject: Регулярные выражения в C++: Использование библиотеки PCRE. Оригинал: http://webcode.ru/re/pcre/ http://webcode.ru/re/pcrelocale/ Поддержка регулярных выражений очень полезна в CGI-программировании. В C++ отсутствуют встроенные механизмы для работы с ними. Разработчик, однако, может воспользоваться библиотекой Perl Compatible Regular Expressions (PCRE), ее исходные коды и документация находятся на сайте http://www.pcre.org. Установка Дистрибутив содержит подробное описание процесса установки библиотеки как в юникс-системах, так и под Windows. В последнем случае потребуется предварительно немного изменить исходные файлы. После компиляции появятся библиотеки pcre.lib и pcreposix.lib, которые следует подключать к проектам, использующим PCRE. Минимальная программа Прежде всего нужно подключить заголовочный файл pcre.h. #include <pcre.h> Для простоты зафиксируем регулярное выражение (шаблон) и строку, которая будет с ним сопоставлена, непосредственно в исходном тексте программы в двух символьных массивах. char pattern[] = "e"; char str[] = "test"; Если необходимо работать со строками на русском языке, можно попытаться подключить соответствующую локаль. О том, как это сделать, рассказано в статье "Локаль в PCRE". Наконец, мы готовы скомпилировать шаблон. Для этого следует вызвать функцию pcre_compile(). В первом аргументе нужно указать ссылку на строку, содержащую регулярное выражение. Во втором параметре можно указать различные атрибуты (соответствующие опциям /igms... в Perl). Следующие два параметра возвращают расшифровку сообщения об ошибках компиляции. В последнем аргументе ожидается NULL или ссылку на таблицу локали. В случае успеха функция вернет указатель на структуру типа pcre. pcre *re; int options = 0; const char *error; int erroffset; re = pcre_compile ((char *) pattern, options, &error, &erroffset, NULL); Примечание. Может оказаться так, что в поставку с компилятором уже входит библиотека PCRE. Однако, конкретная реализация может отличаться от оригинальной. В частности, некоторые популярные компиляторы в определении функции pcre_exec() обходятся без параметра options. Если при компиляции шаблона произошла ошибка, переменная re будет содержать значение NULL. if (!re){ cout << "Failed\n"; } Если ошибки нет, можно вызывать функцию pcre_exec() для поиска совпадений. В первом аргументе передают значение, возвращенное функций pcre_compile(). Следующие три аргумента -- анализируемая строка, ее длинна и смещение, начиная с которого будет обрабатываться строка. Далее идет параметр, указывающий опции (их подробное описание приведено в документации). В последних двух аргументах нужно указать ссылку на массив целых чисел и его длину. else{ int count = 0; int ovector[30]; count = pcre_exec (re, NULL, (char *) str, 4, 0, 0, ovector, 30); После работы функция возвратит число совпадений или отрицательное число в случае ошибки. if (!count){ cout << "No match\n"; Если найдены совпадения, то в массиве ovector будут записаны пары индексов, указывающих на начало и конец совпадений. Первые два элемента массива описывают положение всего совпавшего выражения. Остальные пары -- положение подстрок, которые совпали с выражениями в круглых скобках в шаблоне (это аналоги переменных вида $1 в Perl). Размер массива индексов произволен, но он должен быть кратен трем. Длина определяет максимальное число строк, которые можно получить при сопоставлении с шаблоном, если в нем встретятся подстроки в круглых скобках. В нашем примере (шаблон e и строка test) найдется совпадение со второй буквой в строке. Поэтому первые два элемента массива ovector содержат числа 1 и 2, то есть указывают на совпадение, начинающееся в первой позиции строки и заканчивающееся во второй. Индексация элементов в символьных массивах C++ начинается с нуля. Если шаблон содержит строку (e), в массиве ovector значимыми станут две пары индексов, причем в этом случае они совпадут, поскольку весь шаблон полностью заключен в круглые скобки. Рассмотрим еще один простой пример, записав регулярное выражение e(.)t. Шаблон совпадет с подстрокой est, а в первую переменную попадет подстрока s. Поскольку теперь совпадение начинается с первого символа, а длина совпавшей части равна трем, в первых двух элементах массива ovector появятся значения 1 и 4. Следующая пара -- 2 и 3 (то есть подстрока единичной длины, начинающаяся во второй позиции образца). Полный код Код простейшей программы приведен ниже. Шаблон и строка зафиксированы в ее теле. Программа выводит только пары индексов из массива ovector. #include <iostream.h> #include <pcre.h> int main(){ char pattern[] = "e"; char str[] = "test"; 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){ cout << "Failed\n"; } else{ int count = 0; int ovector[30]; count = pcre_exec (re, NULL, (char *) str, 4, 0, 0, ovector, 30); if (!count){ cout << "No match\n"; } else{ for (int c = 0; c < 2 * count; c += 2){ if (ovector[c] < 0){ cout << "<unset>\n"; } else{ cout << ovector[c] << "/" << ovector[c + 1] << "\n"; } } } } return 0; } Каждый день специально обученный скрипт обращается к Яндексу и ищет этот материал на других серверах. © webcode.ru <mail@webcode.ru.>
Локаль в PCRE Как построить локаль для правильной работы функций PCRE. В предыдущей статье было рассказано о том, как применять библиотеку PCRE (Perl Compatible Regular Expressions) в программах на C++. Здесь же рассказано, как организовать работу библиотеки с текстами на русском языке. Одна из первоочередных задач -- обеспечить правильную работу функций с игнорированием регистра символов. Установка локали Если обратиться к определению функции pcre_compile(), то следует обратить внимание на последний аргумент tableptr: pcre* pcre_compile (const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); Если при вызове этой функции установить последний аргумент в NULL, библиотека воспользуется собственной таблицей pcre_default_tables, которая определена в файле chartables.c, в свою очередь вкомпилированный в библиотечный модуль pcre.lib. Настроить локаль для работы с национальным алфавитом можно как минимум двумя способами. Во-первых, можно исправить упомянутую таблицу до компиляции библиотеки. Второй способ более универсален, его и рассмотрим. Сформировать правильную таблицу локали помогает функция pcre_maketables(). Она не требует передачи аргументов, но <<подсознательно>> учитывает текущую локаль. Поэтому, чтобы построить необходимую таблицу, вначале следует установить локаль обычными средствами, доступными в программе на C++, а затем вызвать pcre_maketables() и сохранить возвращенный результат -- указатель на таблицу локали. Этот указатель следует передать в последнем аргументе при вызове функции pcre_compile(): setlocale (LC_CTYPE, "Russian_Russia.1251"); const unsigned char *locale_tables = pcre_maketables(); re = pcre_compile (pattern, options, errptr, erroffset, locale_tables); Обратите внимание на то, что после того, как построена таблица, функции библиотеки PCRE не учитывают текущую локаль, а работают только с этой таблицей. Это свойство можно с успехом использовать, чтобы не нарушать работу остальных функций, пользующихся локалью. В следующем примере строится таблица необходимой локали, а затем устанавливается локаль, действующая ранее: char *current = setlocale (LC_CTYPE, NULL); char *res = setlocale (LC_CTYPE, locale_string); if (!res) return false; locale_tables = pcre_maketables(); setlocale (LC_CTYPE, current); if (!locale_tables) return false; Переменная locale_string содержит имя локали. О том, как его построить, рассказано в статье "Локаль I". Не следует забывать также и о том, что по окончании работы с таблицей locale_tables ее следует удалить: delete locale_tables; Каждый день специально обученный скрипт обращается к Яндексу и ищет этот материал на других серверах. © webcode.ru <mail@webcode.ru.>

<< Предыдущая ИНДЕКС Правка src / Печать Следующая >>

Обсуждение [ RSS ]
  • 1.1, danila (??), 11:44, 15/10/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    не получается, однако... в точности примеру следую, но при make вываливается ошибка
    main.c:(.text+0x57): undefined reference to 'pcre_compile'
    main.c:(.text+0xb9): undefined reference to 'pcre_exec'
     
  • 1.2, Дмитрий (??), 17:26, 23/12/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    согласен с предыдущим оратором
     
  • 1.3, Mike K (?), 18:13, 26/01/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    gcc -lpcre ...
     
  • 1.4, Alexey (??), 23:22, 01/05/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    А вот почитать следующую штукенцию: man pcre-config ?
    PCRE-CONFIG(1)                                                                                                                                        

    NAME
           pcre-config - program to return PCRE configuration

    SYNOPSIS
           pcre-config [--prefix] [--exec-prefix] [--version] [--libs]
                           [--libs-posix] [--cflags] [--cflags-posix]

    Пример вызова: gcc -Wall  'pcre-config --libs' -o main main.c

     
  • 1.5, Vladislav Kochedykov (?), 20:53, 02/10/2009 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    g++ test-pcre.cpp -o test-pcre -I /usr/local/include/ /usr/local/lib/libpcrecpp.so

    Под FreeBSD я это делаю так.

     
  • 1.6, Анатолий (??), 03:51, 14/05/2011 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Непонятна ссылка на С++... Видно автор не в курсе, но это чисто С-ишная библиотека... Для С++ pcre есть wrapper PCRE с соответствующими классами и было бы логично использовать его. Хотя это конечно дело вкуса... Регулярные выражения это не объектные а функциональные технологии...  В Си есть и класическая библиотека с урезанными возможностями. Там ничего подключать не надо. И часто её бывает достаточно. Глюк там только один, не работает символьный класс \d
     
     
  • 2.7, remarkes (?), 14:46, 07/07/2011 [^] [^^] [^^^] [ответить]  
  • +/
    может быть автор в курсе, но статья видимо рассчитывает на поиск яндекса, который игнорирует букву "C" (англ.) как "язык Си" и ищет что угодно к си не относящееся (пхп там и прочий яваскрипт). Я например на эту страницу попал, набрав "C++ регулярные выражения", разыскивая библиотеку именно для си.
    а вообще, имхо, 99,9% статей и примеров якобы на С++ - чистой воды си
     

  • 1.8, wander (?), 10:13, 30/11/2012 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    В конце статьи delete locale_tables - в корне неверно. delete - это оператор Си++, им нельзя освобождать память выделенную средствами Си. Правильно так:
    pcre_free(locale_tables);
     
  • 1.10, Chepape (?), 21:13, 11/06/2023 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Фукнции в библиотеке написаны говнорукастыми разработчикфми. Нигде нельзя найти нормальное объяснение что фукнция возвращает что принимает. Одним словом лучше не писать код, чем писать код так.
     
  • 1.11, Chepape (?), 21:18, 11/06/2023 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    count  =  pcre_exec  (re,  NULL, (char *) str, 4, 0, 0, ovector, 30);
    Данное выражение не корректно,на деле приходится считывать через while до результата -1, чтобы обработать все шаблоны в строке
     

    игнорирование участников | лог модерирования

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру