Ragel - проверить строку во время ввода
Предположим, мы хотим проверить ввод пользователя, пока пользователь печатает в JTextField. Интересно, могу ли я использовать Ragel для проверки ввода пользователя?
Предположим, что входные данные должны следовать этому примеру регулярного выражения:
[a-z]{2,5}ABC[0-9]+
Как я могу сделать это с помощью ragel? Кто-нибудь может привести короткий пример, как проверить пользовательский ввод "на лету" (при вводе) с помощью ragel?
В документации Ragel отсутствуют некоторые хорошие примеры для быстрого старта, поэтому я спрашиваю здесь.
1 ответ
Вы можете использовать действия EOF (раздел 3.2.2 Действия EOF в документации Ragel) для проверки выражений на лету с помощью Ragel. Они запускаются, когда конец входного буфера обнаружен в допустимом состоянии (включая не окончательный).
Простой пример:
main := ([a-z]{2,5}'ABC'[0-9]+) @/{correct = 1;} %{correct = 1;};
Действие "@/" предназначено для всех не конечных состояний. Включает начальное состояние, поэтому для этого случая правильная пустая строка. Действие "%" предназначено для конечного состояния, когда весь входной буфер соответствует шаблону. В приведенном выше примере код для обоих действий одинаков, но на практике конечное состояние часто должно обрабатываться отдельно. Если это не нужно, приведенный выше пример можно упростить:
main := ([a-z]{2,5}'ABC'[0-9]+) $/{correct = 1;};
Полный образец Ragel с выходом C для проверки предоставленного шаблона приведен ниже. Я надеюсь, что это не проблема, чтобы преобразовать его в Java.
#include <stdio.h>
%%{
machine checker;
write data;
}%%
unsigned char checker( const char *str )
{
/* standart Ragel variables */
const char *p = str, *pe = str + strlen( str ) - 1; //-1 to strip "\n"
const char *eof = pe;
int cs;
unsigned char correct = 0;
%%{
action final { printf("entire match"); correct = 1; }
action partial { printf("partial match"); correct = 1; }
main := ([a-z]{2,5}'ABC'[0-9]+) @/partial %final;
write init;
write exec;
}%%
return correct;
};
#define BUFSIZE 1024
int main()
{
char buf[BUFSIZE];
while ( fgets( buf, sizeof(buf), stdin ) != 0 ) {
printf( "%d\n", checker( buf ));
}
return 0;
}