Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Григорий от Сентябрь 30, 2012, 13:49



Название: Как сделать парсер?
Отправлено: Григорий от Сентябрь 30, 2012, 13:49
 Уважаемые форумчане, есть текст вида   

    text1;text2;text3"text4;text5"text6;"text7;text8"

нужно распарсить текст вот в такой вид

    text1
    text2
    text3"text4;text5"text6
    text7;text8

т.е разделителем подстрок является знак ";", но только если он не находится внутри двойных кавычек,

подскажите как сделать парсер для такого варианта, из того что успел прочитать предлагалось сканировать побайтно или использовать QRegExp, мог бы кто нибудь помочь написать для него строку?


Название: Re: Как сделать парсер?
Отправлено: mutineer от Сентябрь 30, 2012, 14:20
Мне кажется что регулярка тут не поможет и надо парсить посимвольно


Название: Re: Как сделать парсер?
Отправлено: V1KT0P от Сентябрь 30, 2012, 14:27
подскажите как сделать парсер для такого варианта, из того что успел прочитать предлагалось сканировать побайтно или использовать QRegExp, мог бы кто нибудь помочь написать для него строку?
Накой тут регулярка, юзай обычную примитивную функцию(работоспособность не гарантирую, просто пример как делать, сделанно наспех):
Код
C++ (Qt)
#include <QString>
#include <QStringList>
 
void parseLineToList( const QString &line, const QChar &separator, const QChar &escape, QStringList &list )
{
   size_t count = line.size();
   size_t position = 0;
   bool escapeMode = false;
   for( size_t i = 0; i < count; ++i )
   {
       if( escapeMode )
       {
           if( line[i] == escape )
           {
               escapeMode = false;
           }
       }
       else
       {
           if( line[i] == escape )
           {
               escapeMode = true;
           }
           else
           {
               if( line[i] == separator )
               {
                   if( position != i )
                   {
                       list.append( QString( line.data() + position, i - position ) );
                   }
                   position = i + 1;
               }
           }
       }
   }
   if( position != count )
   {
       list.append( QString( line.data() + position, count - position ) );
   }
}
 
int main(int argc, char *argv[])
{
   QString line = "text1;text2;text3\"text4;text5\"text6;\"text7;text8\"";
   QStringList list;
   parseLineToList( line, ';', '"', list );
   return 0;
}


Название: Re: Как сделать парсер?
Отправлено: alex312 от Сентябрь 30, 2012, 14:50
как вариант - http://www.boost.org/doc/libs/1_51_0/libs/tokenizer/escaped_list_separator.htm


Название: Re: Как сделать парсер?
Отправлено: Igors от Сентябрь 30, 2012, 15:54
Не сочтите за бесстыдную саморекламу, просто такие задачки возникают часто

http://www.prog.org.ru/index.php?topic=22338.msg156798#msg156798 (http://www.prog.org.ru/index.php?topic=22338.msg156798#msg156798)


Название: Re: Как сделать парсер?
Отправлено: panAlexey от Октябрь 03, 2012, 17:28
Не сочтите за бесстыдную саморекламу, просто такие задачки возникают часто

http://www.prog.org.ru/index.php?topic=22338.msg156798#msg156798 (http://www.prog.org.ru/index.php?topic=22338.msg156798#msg156798)
Фиг с ней, с рекламой, лишь бы по делу и помогала.
http://www.1cpp.ru/forum/YaBB.pl?num=1253874501
Итоговая регулярка для VBS:
([\d.]+(?=;))|("(([^"])|(""))*"(?=;))



Название: Re: Как сделать парсер?
Отправлено: trot от Октябрь 04, 2012, 08:05
Эта регулярка
Цитировать
([\d.]+(?=;))|("(([^"])|(""))*"(?=;))
не охватывает всех вариантов, например, если точка с запятой стоит после символа отличного от цифры, то такая точка с запятой пропускается. С помощью одного универсального регулярного выражения такую строчку
Цитировать
text1;text2;text3"text4;text5"text6;"text7;text8"
не разбить. но если все таки стоит задачи именно это сделать с помощью регулярных выражений, то надо делать так: с начало вырезаем все подстроки, потом разбиваем и далее вставляем подстроки в результирующий массив там, где они должны быть. Конечно этот вариант проигрывает с тем, что предложено выше.