В обработке вывода от ESP8266 мне очень помогла библиотека регулярных выражений T-Rex [1]. К сожалению, эту библиотеку получится использовать не на всех AVR, потому что её подключение требует целых 8 килобайт памяти программ. Однако если у Вас микроконтроллер наподобие ATmega328 или ATmega32U4, то вполне можете воспользоваться обработкой регулярных выражений с помощью T-Rex.
[Как использовать T-Rex]
Здесь приведен пример использования библиотеки регулярных выражений - проверка строки на IP-адрес.
1. Создайте регулярное выражение на основе структуры типа TRex (в этом примере показано простейшее регулярное выражение для проверки IP-адреса). Можете воспользоваться online-тестером регулярных выражений, как например [2]. С помощью функции trex_compile подготовьте регулярное выражение:
Примечание: метасимвол ^ означает начало строки, \d задает цифры, {1,3} задает количество повторений цифр от 1 до 3, $ означает конец строки.
Обратите внимание, что спецсимволы ('d', '.' и т. п.) экранируются дважды - одно экранирование требует синтаксис regex, второе экранирование требует синтаксис языка C.
2. Проверьте, успешно ли было скомпилировано регулярное выражение (возвращенное функцией компиляции значение x не должно быть равно нулевому указателю), после чего функцией trex_match проверьте, прошла ли проверка на соответствие строки регулярному выражению.
if (x)
{
if (trex_match(x, inputIP))
{
//Успешное совпадение!
}
else
{
//Проверка на IP не прошла.
printf(USB_out, "Нет совпадения!\r\n");
}
trex_free(x);
}
Обратите внимание, что если регулярное выражение было скомпилировано успешно (x!=0), то нужно по завершении работы с регулярным выражением обязательно освободить память вызовом trex_free.
3. С помощью функций trex_getsubexpcount и trex_getsubexp Вы можете прочитать подстроки регулярного выражения, которые Вы ограничили круглыми скобками. Вот пример чтения по байтам IP-адреса:
...
if (trex_match(x, regexinput))
{
int i,n = trex_getsubexpcount(x);
TRexMatch match;
for(i =0; i < n; i++)
{
char t[10];
trex_getsubexp(x,i,&match);
strncpy(t,match.begin,match.len);
printf("%i байт IP = %s\r\n",i+1, t);
}
}
...
trex_free(x);
...
[Синтаксис регулярных выражений, который поддерживает T-Rex]
К сожалению, из заявленного синтаксиса поддерживается не все, у меня были проблемы с "жадными" выражениями. Например {n,} (означает не меньше n повторений) не поддерживается, нужно обязательно задавать правую границу, вот так {n, m} (означает, что повторений может быть от n до m). Также не поддерживается +.
Компилирует регулярное выражение (подготавливает его для использования) и возвратит указатель на его скомпилированную версию. В случае неудачи вернет NULL. Возвращенное значение должно быть удалено (после использования) с помощью функции trex_free().
Параметры:
pattern указатель на ASCIZ-строку (строка, оканчивающаяся 0), в которой содержится компилируемое регулярное выражение.
error указатель на строку, в которую будет записано сообщение об ошибке, если компиляция завершилась неудачно.
Ищет первое совпадение выражения exp в строке, указанной параметром text. Если совпадение найдено, то функция вернет TRex_True, и установит out_begin на начало совпадения, и out_end на конец совпадения; иначе вернет TRex_False.
Параметры:
exp скомпилированное регулярное выражение.
text строка текста, в которой будет осуществляться поиск.
out_begin указатель на строковый указатель, в который будет загружено значение, указывающее на начало совпадения.
out_end указатель на строковый указатель, в который будет загружено значение, указывающее на конец совпадения.
Ищет первое совпадение выражения exp в части строки, которая ограничена указателями в параметрах text_begin и text_end. Если совпадение найдено, то будет возвращено TRex_True, и в out_begin будет записан адрес начала совпадения, и в out_end будет записан конец совпадения; иначе будет возвращено TRex_False.
Параметры:
exp скомпилированное регулярное выражение.
text_begin указатель на начало проверяемой строки.
text_end указатель на конец проверяемой строки.
out_begin указатель на строковый указатель, который будет заполнен адресом начала совпадения.
out_end указатель на строковый указатель, который будет заполнен адресом конца совпадения.