SLRE: сверхлегкая библиотека обработки regex |
![]() |
Добавил(а) microsin |
Еще один кандидат обработки регулярных выражений на микроконтроллерах - библиотека SLRE [1] (аббревиатура SLRE означает Super Light Regular Expression library). Возможно, этот вариант даже лучше, чем T-Rex [2]. Основное отличие от T-Rex в том, что меньше требуется места под код (5 килобайт вместо 8), и не используется динамическое выделение памяти malloc (вместо этого задействован стек). Автор библиотеки Sergey Lyubka (см. файл slre.h), он доброжелательно отвечает на вопросы, связанные с библиотекой. SLRE можно использовать на условиях лицензии GNU GPL v.2, также есть возможность покупки коммерческой лицензии, которая не предусматривает лицензионных отчислений. Здесь приведен перевод оригинальной документации SLRE, опубликованной на GitHub [1]. Код SLRE совместим со стандартом ISO C / ANSI C'89. Библиотека SLRE реализует проверку подмножества синтаксиса регулярных выражений Perl. В частности, не поддерживаются фигурные скобки, позволяющие точно задавать количество повторений в регулярном выражении. Библиотека легко расширяется. Например, если Вам нужно добавить новый метасимвол \i, означающий IP-адрес IPv4, то с помощью SLRE это сделать просто. SLRE отлично справляется с задачами обработки сетевых запросов, файлов конфигурации, консольного ввода пользователя (командной строки) и т. п. Библиотеку SLRE целесообразно применять в тех местах, где библиотеки наподобие PCRE становятся слишком ресурсоемким выбором - разработчики встраиваемых систем получат при использовании SLRE наибольшее преимущество. [Синтаксис, поддерживаемый SLRE] ^ Совпадение с началом строки. $ Совпадение с концом строки. () Группирование символов проверяемого текста с целью извлечения его фрагментов (substring capturing). \s Совпадение с пробелом. \S Совпадение с любым символом, не совпадающим с пробелом. \d Совпадение с десятичной цифрой. \n Совпадение с символом перехода на новую строку (LF). \r Совпадение с символом возврата каретки (CR). \f Совпадение с символом перевода страницы (FF). \v Совпадение с символом вертикальной табуляции. \t Совпадение с символом горизонтальной табуляции (TAB). \b Совпадение с символом backspace. + Совпадение в одно или большее количество раз (жадный режим обработки). +? Совпадение в одно или большее количество раз (не жадный, или ленивый режим). * Совпадение ноль или большее количество раз (жадный режим обработки). *? Совпадение ноль или большее количество раз (не жадный, или ленивый режим). ? Совпадение совпадение ноль или один раз (не жадный, или ленивый режим). x|y Совпадение с x или с y (оператор вариантов ИЛИ). \meta Совпадение с одним из метасимволов: ^$().[]*+?|\ (экранирование специальных символов). \xHH Совпадение с байтом, указанным в hex-формате, например \x4a (0x4A). [...] Совпадение любым символом из набора. В квадратных скобках перечисляются символы для совпадения, или задается их диапазон наподобие [a-z]. [^...] Совпадение с любым символом, который не входит в указанный набор. В жадном режиме (по умолчанию) алгоритм регулярных выражений ищет соответствие квантификатору настолько много раз, насколько это возможно. Обратный этому ленивый режим, он проверяет соответствие минимальное количество раз. Подробнее см. [3]. [Как применять библиотеку SLRE] API библиотеки чрезвычайно простой. Это единственная функция slre_match, которая обнаруживает совпадение, и структура slre_cap, которая предназначена для выборок из регулярного выражения (фрагментов проверяемого текста, обозначенных в регулярном выражении круглыми скобками). struct slre_cap { char *ptr; int len; }; int slre_match(char *regexp, char *buf, int buf_len, struct slre_cap *caps, int num_caps, int flags); regexp указатель на строку ASCIIZ, в которой записано регулярное выражение. buf указатель на проверяемую строку текста (она проверяется на соответствие с регулярным выражением). buf_len длина строки проверяемой текста в байтах. caps ссылка на массив структур slre_cap. В этом массиве должно быть столько же элементов, сколько в регулярном выражении встречается пар круглых скобок. Если одна пара круглых скобок, то это может быть указатель на один объект slre_cap. num_caps количество пар круглых скобок (должно быть равно количеству элементов массива caps). flags флаги, которые учитываются при обработке строки на соответствие регулярному выражению. Пока что поддерживается единственный флаг SLRE_IGNORE_CASE, который включает игнорирование регистра символов текста проверяемой строки (маленькие буквы считаются эквивалентными большим). Функция slre_match вернет количество обработанных байт проверяемой строки от её начала. Если возвращенное значение значение больше или равно 0, то было обнаружено совпадение строки с регулярным выражением. Если же возвращено отрицательное значение, то это означает ошибку (совпадение не обнаружено). Возвращаемые коды ошибки: #define SLRE_NO_MATCH -1 //совпадение не обнаружено #define SLRE_UNEXPECTED_QUANTIFIER -2 //неожиданный квантификатор, т. е. *, +, ?, { и } #define SLRE_UNBALANCED_BRACKETS -3 //непарные круглые скобки #define SLRE_INTERNAL_ERROR -4 //внутренняя ошибка #define SLRE_INVALID_CHARACTER_SET -5 //недопустимый набор символов #define SLRE_INVALID_METACHARACTER -6 //недопустимый метасимвол, т. е. \, ^, $ и т. д. #define SLRE_CAPS_ARRAY_TOO_SMALL -7 //массив для фрагментов слишком мал #define SLRE_TOO_MANY_BRANCHES -8 //слишком много ветвлений #define SLRE_TOO_MANY_BRACKETS -9 //слишком много скобок Пример обработки запроса HTTP: const char *request = " GET /index.html HTTP/1.0\r\n\r\n"; struct slre_cap caps[4]; if (slre_match("^\\s*(\\S+)\\s+(\\S+)\\s+HTTP/(\\d)\\.(\\d)", request, strlen(request), caps, 4, 0) > 0) { printf("Метод: [%.*s], URI: [%.*s]\n", caps[0].len, caps[0].ptr, caps[1].len, caps[1].ptr); } else { printf("Ошибка обработки [%s]\n", request); } Пример поиска ссылок URL в строке: static const char *str = "< img src=\"HTTPS://FOO.COM/x?b#c=tab1\"/> " " < a href=\"http://cesanta.com\" >some link< /a>"; static const char *regex = "((https?://)[^\\s/'\"< >]+/?[^\\s'\"< >]*)"; struct slre_cap caps[2];int i, j = 0, str_len = strlen(str); while (j < str_len && (i = slre_match(regex, str + j, str_len - j, caps, 2, SLRE_IGNORE_CASE)) > 0) { printf("Найден URL: [%.*s]\n", caps[0].len, caps[0].ptr); j += i; } Вывод: Найден URL: [HTTPS://FOO.COM/x?b#c=tab1] Найден URL: [http://cesanta.com] Библиотеку SLRE следует применять с осторожностью в случае, если мало осталось свободной памяти RAM, потому что стек может перезаписать области памяти переменных (вызовы slre_match помещают в стек объемную служебную структуру regex_info). Для снижения требований на место под стек можно уменьшить значения констант MAX_BRANCHES и MAX_BRACKETS (по умолчанию они равны 100). #define MAX_BRANCHES 100 #define MAX_BRACKETS 100 Если уменьшить обе эти константы до 5, то размер структуры regex_info уменьшается до 70 байт. [Ссылки] 1. SLRE: Super Light Regular Expression library site:github.com. |