Re: Паттерны на Си, надо выкусить нормальные слова из мусора
От: Кодт Россия  
Дата: 05.08.03 08:52
Оценка: 14 (6)
Здравствуйте, Аноним, Вы писали:

А>Помогите написать паттерн для выкусывания текста из файла с мусором, может какой-нибудь более нормальный путь есть?


sscanf'ом здесь не обойдешься: он не запоминает, где закончил разбор.

Что считать текстом? Например, такое определение:
— текст — это последовательность слов, разделенных пробелами (общей длиной не менее 2 знаков)
— слово — это непустая последовательность букв [A-Za-z]
— код — это что угодно кроме текста

Строим конечный автомат:
START --> CODE, запомнить позицию C

CODE , A-Z|a-z       --> TEXT1, запомнить позицию T
CODE , ?             --> CODE
CODE , end           --> вывести код от C до текущей, конец

TEXT1, A-Z|a-z|space --> TEXT, вывести код от C до T, сбросить C
TEXT1, ?             --> CODE
TEXT1, end           --> вывести код от C до текущей, конец

TEXT , A-Z|a-z|space --> TEXT
TEXT , ?             --> CODE, вывести текст от T до текущей, сбросить T, запомнить C
TEXT , end           --> вывести текст от T до текущей, конец


И пишем прогу
void print_begin();
void print_text(const char* s, int len);
void print_code(const char* s, int len);
void print_end();

void parse(const char* s)
{
  print_begin();

  const char* pc = s;
  const char* pt = NULL;
  char ch;
  enum { CODE, TEXT1, TEXT } st = CODE;

  while(true)
  {
    ch = *s;

    switch(st)
    {
    case CODE:
      if     (ch == 0)     { print_code(pc, s-pc); print_end(); return; }
      else if(isalpha(ch)) { pt = s; st = TEXT1; }
      else                 { }
      break;
    case TEXT1:
      if     (ch == 0)                    { print_code(pc, s-pc); print_end(); return; }
      else if(isalpha(ch) || isspace(ch)) { print_code(pc, pt-pc); pc = NULL; }
      else                                { st = CODE; pt = NULL; }
      break;
    case TEXT:
      if     (ch == 0)                    { print_text(pt, s-pt); print_end(); return; }
      else if(isalpha(ch) || isspace(ch)) { }
      else                                { print_text(pt, s-pt); st = CODE; pt = NULL; pc = s; }
      break;
    }

    ++s;
  }
}

Вот примерно так.
(Программу не отлаживал, не обессудьте).
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.