...Работы у меня сегодня не было, а настроение поизвращаться с C++ — было.
В результате всего этого, появился "шедевер" — шаблонная библиотека статических регулярных выражений, в чем-то смахивающая на SPIRIT. Вот только она гаараздо меньше — всего 7 килобайт. Ну, и гораздо примитивнее, конечно.
Основная ее фишка в том, что компиляция регулярного выражения проводится на этапе компиляции программы — прямо в исполнимый код (довольно страшноватенький — т.к. оптимизация еще впереди). А на этапе выполнения остается только пользоваться функцией поиска совпадений...
пример:
//задаем регулярное выражение (обьяснение примитивов будет ниже)
namespace myrx
{
using namespace rx_tmpl;
typedef //определяем регулярное выражение для выделения числа
//с плавающей точкой: [+-]?[0-9]+(\.[0-9]+)?([Ee][+-]?[0-9]+)?
seq<
opt<set<'+','-'> >,
plus<digit>,
opt<seq<c<'.'>, plus<digit> > >,
opt<seq<set<'E','e'>, opt<set<'+','-'> >, plus<digit> > >
>
float_num;
}
//применяем его...
void function()
{
string number("123.45E-56 some text");
string::iterator it = number.begin();
if( myrx::float_num::match(it, number.end()) )
{
//строка совпала.
//итератор it указывает на позицию сразу за числом
} else {
//строка не совпала
//позиция итератора не изменилась.
}
}
примитивы:
c<'A'> - литеральный символ.
s<'H','E','L','L','O'> - литеральная строка
set<'A','B','C','D','E','F'> - набор символов - как [ABCDEF].
range<'A','Z'> - диапазон символов - как [A-Z].
range<'A','Z',false> - диапазон символов - как [^A-Z].
ws - пробел или таб [ \t]
digit - цифра - как [0-9]
alpha - английская буква без учета регистра - как [A-Za-z]
star<RX> - ноль или более совпадений - как (abcd)*
plus<RX> - одно или более или более совпадений - как (abcd)+
opt<RX> - необязательное совпадение - как (abcd)?
alt<RX1,RX2> - альтернатива - как (abc|def)
seq<RX1,RX2,RX3,....,RX10> - конкатенация регулярных выражений
ЗЫ. Код будет в следующем сообщении в этой же нитке.