Russian Qt Forum

Qt => Общие вопросы => Тема начата: Torvald от Май 01, 2014, 11:46



Название: Парсинг строки определенного типа
Отправлено: Torvald от Май 01, 2014, 11:46
Здравствуйте, есть строки вида:
1. "-Y 1 +X 1"
2. "-Y 1024 +X 1024"
3. "#Year 1536 count 1024"
4. "+Y 128 +X 128"

Необходимо считать числа M и N в строках вида "-Y M +X N", то есть в моем примере строки 1 и 2 валидные, а строки 3 и 4 нужно отбросить. Так же строки могут быть пустыми и без пробелов.
Вопрос: как это сделать средствами Qt не прибегая к sscanf и желательно без регулярных выражений?

Регэкспы кажутся медленными (хотя могу ошибаться, скорость не замерял), так что пока мое решение такое:
1. Сплит строки по пробелам
2. Если элементов 4, то:
2.1. Если 0 и 2 подстроки "-Y" и "+X" соответственно, то подстроки 1 и 3 конвертируем к интам


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 01, 2014, 12:57
Цитировать
Регэкспы кажутся медленными (хотя могу ошибаться, скорость не замерял), так что пока мое решение такое:
1. Сплит строки по пробелам
2. Если элементов 4, то:
2.1. Если 0 и 2 подстроки "-Y" и "+X" соответственно, то подстроки 1 и 3 конвертируем к интам

Так предложенный вами вариант, будет ещё медленней  :)
Не говоря уже о том, что и менее гибкий..


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 01, 2014, 17:02
Пролетать по строке, проверяя каждый символ. Если сочетание, то следующие символы до пробела конвертируем в число и вносим соответственно сочетанию.

Т.е. QString и indexOf или же char * и char[] :)


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 02, 2014, 05:53
Отрадно видеть заботу о скорости :) Да, split создает контейнер, выделяет память на каждый эл-т - все это недешево, и за удобство придется платить производительностью. Но о каких данных идет речь? Если тех строк до 2 Mb (на глазок), то на расходы можно спокойно забить. Если "выжимать" то придется немного потрудиться и сделать базовую ф-цию напр
Код
C++ (Qt)
QStringRef NextWord( QStringRef & str ); // возвращает следующее "слово" в строке
А дальше уже несложно накрутить. Кстати разделитель может быть не только пробел но и таб.


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 02, 2014, 11:10
Без сомнения всё может быть, но в приведённом примере разделитель пробел :)


Название: Re: Парсинг строки определенного типа
Отправлено: kambala от Май 02, 2014, 13:11
для подобных задач регулярки и были придуманы


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 02, 2014, 13:20
Они избыточны на таком формате по моему мнению :)


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 02, 2014, 13:55
Без сомнения всё может быть, но в приведённом примере разделитель пробел :)
Откуда такая уверенность? Размер табуляции = 1 не запрещен. И Ваша логика недоступна моему пониманию: работать должен только "этот" пример или как?  :)

для подобных задач регулярки и были придуманы
Ну как пойдет частокол слешей - то все, ховайся  :)


Название: Re: Парсинг строки определенного типа
Отправлено: kambala от Май 02, 2014, 14:05
Они избыточны на таком формате по моему мнению :)
на мой взгляд в данном случае избыточным будет это:
Пролетать по строке, проверяя каждый символ. Если сочетание, то следующие символы до пробела конвертируем в число и вносим соответственно сочетанию.
1. Сплит строки по пробелам
2. Если элементов 4, то:
2.1. Если 0 и 2 подстроки "-Y" и "+X" соответственно, то подстроки 1 и 3 конвертируем к интам
регулярка решает задачу одной строкой («правилом», как в другой теме :) )
для подобных задач регулярки и были придуманы
Ну как пойдет частокол слешей - то все, ховайся  :)
в С++11 это уже не проблема с литеральными строками ;)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 02, 2014, 14:37
Регулярное выражение с правилами займёт больше времени выполнения, чем "просто пролетать по строке". Проверял неоднократно.

И да, ваше регулярное выражение так же "пролетает по строке", выдёргивая всё что надо :)

to Igors: я решаю задачи. Везде. Есть задача - имеется данный формат, описания нет, есть строка. Как распарсить. Ответ дан. Дополнительные условия не приведены, следовательно посылать всех лесом, кто воскликнет - А ЕСЛИ?


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 02, 2014, 14:44
Регулярное выражение с правилами займёт больше времени выполнения, чем "просто пролетать по строке". Проверял неоднократно.
Может проверим ещё раз? :)
Пишите пролетайку по строке, а я напишу вариант с регулярками.
А то вы все задачи решаете, а решений что-то не видать. Одни слова.


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 02, 2014, 15:55
to Old: необоснованная критика, ай ай ай :)
Если хотите - напишите сами варианты прогонки "с" и "без" RegExp используя только Qt :)
Использовать сторонние утилиты и реализации запрещено.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 02, 2014, 16:14
Сам не хочу. :)
По вашим "проскокам по строке" я понял, что вы легко это сможете сделать. Наверное я ошибся.

А в чем заключается критика, да ещё и не обоснованная? Я просто предложил проверить, ваше голословное заявление.

И почему такие странные ограничения по инструментам, мы хотим проверить регулярку против проскока по строке? Ну если вы захотите это проверить, а не просто "поговорить", то я готов использовать регулярку Qt.


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 02, 2014, 16:21
Извиняюсь, но это раздел Qt, общие вопросы :)

Предложить ваш способ вы вправе, так же как и иметь своё мнение :) Но человеку, ещё не освоившему Qt, предлагать осваивать буст  - это бессмысленно.

PS я про
А то вы все задачи решаете, а решений что-то не видать. Одни слова.
. Подтверждений моих слов на форуме хватает в виде исходников в архивах, так что критика не обоснована. И в этот раз мне не хочется делать велосипед в очередной раз и без цели. Ведь я уже видел результаты :) И да - проверить хотите вы. Инициатива .... инициатора.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 02, 2014, 16:28
Какой буст? Причём здесь буст?


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 02, 2014, 16:40
Извиняюсь, но это раздел Qt, общие вопросы :)
Нехорошо, за базар отвечать надо. А то сначала резво даете советы, посылаете лесом, а как доходит до дела - так сами в кусты.

По поводу регулярок: верю что это легко делается. Но вот что с контролем ошибок? Могу ли я предъявить юзверю напр
Цитировать
-Y 10и24 +X 1024
Error: integer expected
Это всякий раз охлаждает мой энтузиазм когда я собираюсь в конце-концов зазубрить правила/синтаксис  :) (заметим что в варианте ТС с этим проблем нет)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 02, 2014, 17:20
Но вот что с контролем ошибок?
Изначально нужно решить, как мы используем регулярку?
Например, есть массив данных, в которых нам нужно найти данные по шаблону (последовательность-число последовательность-число), тогда все что не попадает под этот шаблон будет просто пропущено. А можно задать шаблон и проверять каждую строку на его соответствие и если его нет выдавать сообщение об ошибке.
Если вы про второй вариант, то да - можно.


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 02, 2014, 17:38
Например, есть массив данных, в которых нам нужно найти данные по шаблону (последовательность-число последовательность-число), тогда все что не попадает под этот шаблон будет просто пропущено.
Пусть не всегда но часто меня "просто пропущено" не устраивает - надо предъявить где насистели

А можно задать шаблон и проверять каждую строку на его соответствие и если его нет выдавать сообщение об ошибке. Если вы про второй вариант, то да - можно.
Тогда (в данном примере) какие варианты кроме чтения "слов" последовательно (подобно тому что я предложил выше) ?


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 02, 2014, 17:39
Закончим с нападками в мою сторону.
Когда я хочу что-то доказать кодом, я доказываю кодом.
Когда пишу своё мнение - это моё мнение. Мнение может обсуждаться и опровергаеться, но до того - оно истинно для меня :)

PS ппц смотрю и всё печальнее становится. Ради 2 минут простейшей работы и получении опыта программирования, давайте пихать готовые решения. Написание собственных велосипедов - часть , если не 90% пути программиста.

PPS прекратите засорять тему ТС-са рассуждениями ах если бы кабы, да кабы. А то это уже 3(или 4) тема, которую вы с Igors сводите к собственным разбирательствам как же ж можно. Создайте отдельную и её продолжайте :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 02, 2014, 17:47
PS ппц смотрю и всё печальнее становится. Ради 2 минут простейшей работы и получении опыта программирования, давайте пихать готовые решения. Написание собственных велосипедов - часть , если не 90% пути программиста.
Так и показали бы нам, свой кунг-фу. А то пару минут простейшей работы... уже бы сделали давно и сравнили. :)

Вы без Qt не сможете сделать ничего, вообще ничего, о каких велосипедах и 90% пути программиста вы говорите? :)
Почему то, навороченный класс QString вы готовым решением не считаете, а если вместе с QString использовать QRegExp, то это сразу становиться готовым решение, недостойным настоящего программиста. :)
Ну так откажитесь и от QString? Но думаю без него вы эту задачу вообще не решите.

PPS прекратите засорять тему ТС-са рассуждениями ах если бы кабы, да кабы. А то это уже 3(или 4) тема, которую вы с Igors сводите к собственным разбирательствам как же ж можно. Создайте отдельную и её продолжайте :)
Поверьте, я без вас разберусь, что и как мне делать. ;)
И ТС от этого есть польза, он развеет заблуждение о том, что регулярка медленее "проскока строки". И к тому же проще и надежней.


Название: Re: Парсинг строки определенного типа
Отправлено: kambala от Май 02, 2014, 18:05
на всякий случай напишу «регулярное» решение: \-Y\s*(\d+)\s*\+X\s*(\d+) Результаты будут храниться в $1 и $2 для M и N соответственно (если совпадение найдено конечно).

превратить это в C++/Qt код оставлю любознательному читателю :)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 02, 2014, 18:18
А вот  kambala респект :D
to Igors, Old: инициатива .... инициатора. Вам надо, вы и сравнивайте :)
PS задача спокойно решается с учебником по любому языку программирования за 15-30 минут. Направление задано, алгоритмы работы без регэксп приведены мной, регэксп приведён камбалой. Осталось только ТС-су потратить чуть времени :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 02, 2014, 18:22
Вот и прочли бы этот учебник - толку было бы больше, чем ерунду набирать.


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 02, 2014, 18:24
to Old: сообщения без смысла теперь игнорю. :) И вам удачных праздников.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 02, 2014, 18:43
to Old: сообщения без смысла теперь игнорю. :)
А как вы их будете набирать? А, впрочем, понятно "как". :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 02, 2014, 18:52
Тогда (в данном примере) какие варианты кроме чтения "слов" последовательно (подобно тому что я предложил выше) ?
Как я и описал. Задаем правило (например, как написал kambala), читаем строку, матчим ее с шаблоном, если прошли, то конвертируем строки в числа, если нет - выдаем ошибку.


Название: Re: Парсинг строки определенного типа
Отправлено: vizir.vs от Май 05, 2014, 13:15
на всякий случай напишу «регулярное» решение: \-Y\s*(\d+)\s*\+X\s*(\d+) Результаты будут храниться в $1 и $2 для M и N соответственно (если совпадение найдено конечно).

превратить это в C++/Qt код оставлю любознательному читателю :)

Мне кажется, что между Y и X должны быть обязательно пробелы, поэтому надо заменить \s* на \s+ после X и Y. Возможно перед +X так же обязательно нужен пробел, можно и там заменит \s* на \s+. Плюс, хорошо бы указать что это целая строка, т.е. указать в начале ^ в конце $.
Получаем ^\-Y\s+(\d+)\s+\+X\s+(\d+)$


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 05, 2014, 15:41
Как я и описал. Задаем правило (например, как написал kambala), читаем строку, матчим ее с шаблоном, если прошли, то конвертируем строки в числа, если нет - выдаем ошибку.
А что Вы можете выдать? "В строке xxx ошибка" - а где? Регулярка очень хороша для поиска по файлу(ам) когда "нет - ну значит и нет". Но во многих др случаях простецкое решение (типа как предложил ТС) может оказаться гибче и, в конечном счете, выгоднее.

Лучше быть хоть на 1 ход впереди заказчика (разумеется не надо ему об этом сообщать). Сейчас он хочет -Y и +X. А чего не +Y и не -X? Или оба X и Y могут иметь любые знаки. Или вообще без знака (+ по умолчанию). Или могут следовать в любом порядке. Или добавляется однотипная Z координата. Или любой из параметров отсутствует (или принимается по умолчанию). Во всех этих случаях Вам придется немало посуетиться с гордым/крутым "решением в 1 строку" и оно станет не таким уж простым. В то же время тупенький разбор "слово за словом" выдержит эту нагрузку без проблем.

Конечно можно возразить в стиле Верес'a - типа "мне такой задачи не давали!!!", но это несерьезно  :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 15:47
А что Вы можете выдать?
А вы?
Я быстро нахожу строку с ошибкой, дальше я могу ее под микроскопом проходить и выдавать полную диагностику. :)

Лучше быть хоть на 1 ход впереди заказчика (разумеется не надо ему об этом сообщать). Сейчас он хочет -Y и +X. А чего не +Y и не -X? Или оба X и Y могут иметь любые знаки. Или вообще без знака (+ по умолчанию). Или могут следовать в любом порядке. Или добавляется однотипная Z координата. Или любой из параметров отсутствует (или принимается по умолчанию). Во всех этих случаях Вам придется немало посуетиться с гордым/крутым "решением в 1 строку" и оно станет не таким уж простым. В то же время тупенький разбор "слово за словом" выдержит эту нагрузку без проблем.
Эти умозаключения вы выдаете потому, что понятия не имеете о регулярках. Да? :)

Конечно можно возразить в стиле Верес'a - типа "мне такой задачи не давали!!!", но это несерьезно  :)
Так вы поступаете так же. :)
Вспомните тему про парсер BibTex.


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 05, 2014, 16:04
Здравствуйте, форумчане. : )
Цитировать
Может проверим ещё раз?
Тоже стало интересно. Решил сделать сравнительные тесты.
Итак приблизительные (средняя скорость) результаты по скорости выполнения (на моей виртуальной машине : ) ):

Метод ТСа:
    TS method
    Time elapsed =  206

Регексп:
     RegExp method.
     Time elapsed =  361

Файнд (моя реализация):
     Find method.
     Time elapsed =  135

Итак, РегЕкспы уверенно идут сзади. Метод ТСа так же не очень оптимальный. Итого - выигрывают велосипеды! : )

Моё мнение такое, что РегЕкспы на этой конкретной задаче не будут быстрее, ибо они избыточны. Так же не стоит забывать, что мы платим скоростью за удобство. Так что для таких мелких задач стоит использовать велосипеды, которые будут заточены под конкретную задачу.

ПС. Если кто-то заметил ошибки в коде, пожалуйста, сообщите. Я поправлю и проведу тесты повторно. Так же было-бы неплохо провести их хотя-бы на еще одной машине.

Сорцы:

Код:
#include <QCoreApplication>

#include <QVector>
#include <QStringList>
#include <QDebug>
#include <QRegExp>
#include <QElapsedTimer>

//#define TS
//#define REGEXP
//#define FIND

QVector<QString> GenerateList()
{
    QVector<QString> mVec;
    for (size_t ix = 0; ix < 100000; ++ix)
    {
        mVec.push_back(QString("-Y " + QString::number(qrand()) + " +X " + QString::number(qrand())));
    }

    return mVec;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QVector<QString> mVec = GenerateList();

    int y_value;
    int x_value;

    QElapsedTimer mTimer;
    mTimer.start();

#ifdef TS

    qDebug() << "TS method";

    foreach (const QString &line, mVec) {

        QStringList mSubLines = line.split(" ");

        // Handle error.
        if (mSubLines.size() != 4)
            continue;

        // Handle error.
        if (mSubLines.at(0) != "-Y" || mSubLines.at(2) != "+X")
            continue;
#ifdef DEBUG
        qDebug() << "First = " << mSubLines.at(1).toInt();
        qDebug() << "Second= " << mSubLines.at(3).toInt();
        qDebug() << endl;
#endif
        y_value = mSubLines.at(1).toInt();
        x_value = mSubLines.at(3).toInt();
    }

#endif

#ifdef REGEXP

    qDebug() << "RegExp method.";

    QRegExp mRegExp;
    mRegExp.setPattern("^\\-Y\\s+(\\d+)\\s+\\+X\\s+(\\d+)$");

    foreach (const QString &line, mVec) {
        // Handle error.
        if (mRegExp.indexIn(line) != -1) {
#ifdef DEBUG
            qDebug() << "First = " << mRegExp.cap(1).toInt();
            qDebug() << "Second= " << mRegExp.cap(2).toInt();
#endif
            y_value = mRegExp.cap(1).toInt();
            x_value = mRegExp.cap(2).toInt();
        }
    }

#endif

#ifdef FIND

    qDebug() << "Find method.";

    foreach (const QString &line, mVec) {
        //Handle error.
        if (!line.startsWith("-Y "))
            continue;

        int posX = 0;

        // Handle error.
        if ((posX = line.indexOf(" +X ")) == -1)
            continue;

        // len of "-Y " str.
        const int yValueStartPos = 3;

        // Position after Y value.
        int yValueEndPos = line.indexOf(" ", yValueStartPos);

        // Handle error.
        if (yValueEndPos == -1)
            continue;

#ifdef DEBUG
        // 4 is length of " +X " str.
        qDebug() << line.mid(yValueStartPos, yValueEndPos - yValueStartPos);
        qDebug() << line.mid(posX + 4, line.indexOf(" ", posX));
        qDebug() << endl;
#endif
        y_value = line.mid(yValueStartPos, yValueEndPos - yValueStartPos).toInt();
        x_value = line.mid(posX + 4, line.indexOf(" ", posX)).toInt();
    }

#endif

    qDebug() << "Time elapsed = " << mTimer.elapsed();

    return a.exec();
}


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 05, 2014, 16:08
Эти умозаключения вы выдаете потому, что понятия не имеете о регулярках. Да? :)
Ну чего Вы такой "нервный и желчный субъект" (как писали классики)? Не стоит отвечать сразу полагая что "все ясно, он НЕ ЗНАЕТ :) ". Поверьте, есть люди которые пытаются думать и анализировать, и это нормально

Вспомните тему про парсер BibTex.
А что собственно я должен вспоминать? :) Что я предложил нормальный код на C++ решающий задачу и доступный для дальнейшей поддержки и развития любому нормальному программисту? Так здесь мне стыдиться нечего  :)


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 05, 2014, 16:10
Цитировать
Во всех этих случаях Вам придется немало посуетиться с гордым/крутым "решением в 1 строку" и оно станет не таким уж простым. В то же время тупенький разбор "слово за словом" выдержит эту нагрузку без проблем.

Разбор "слово за словом" при новых условиях придётся модифаить. Как и регексп. Как и фаинд. А изменения не станут проблемой, в принципе, ни в одном из случаев.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 16:12
Ну чего Вы такой "нервный и желчный субъект" (как писали классики)?
А почему вы все время думаете что я нервно исхожу желчью? :)
Вы пишите очень наивные вещи, которые пугают исключительно вас. Это выглядит очень наивно, поэтому я и спросил. :)

А что собственно я должен вспоминать? :) Что я предложил нормальный код на C++ решающий задачу и доступный для дальнейшей поддержки и развития любому нормальному программисту? Так здесь мне стыдиться нечего  :)
Не, просто вы сразу поставили кучу условий и потребовали синтетические тесты на одном файле, которые кстати не прошли. :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 16:19
ПС. Если кто-то заметил ошибки в коде, пожалуйста, сообщите. Я поправлю и проведу тесты повторно. Так же было-бы неплохо провести их хотя-бы на еще одной машине.
Попробуйте использовать не такие синтетические файлы. :)
Пусть со всех сторон могут быть разное число пробелов, табуляций и прочих комментариев. Что ближе к реальности. ;)


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 05, 2014, 16:24
ПС. Если кто-то заметил ошибки в коде, пожалуйста, сообщите. Я поправлю и проведу тесты повторно. Так же было-бы неплохо провести их хотя-бы на еще одной машине.
Попробуйте использовать не такие синтетические файлы. :)
Пусть со всех сторон могут быть разное число пробелов, табуляций и прочих комментариев. Что ближе к реальности. ;)

Таки ближе к реальности мои тесты. Например, у себя в проекте я писал парсер PLS файлов. PLS файлы от веб-сервиса, как правило, приходили без лишних пробелов, табов, и тд.

Сделал так, ничего кардинально не изменилось:
Цитировать
QVector<QString> GenerateList()
{
    QVector<QString> mVec;
    int counter = 0;
    for (size_t ix = 0; ix < 100000; ++ix)
    {
        if (counter == 5)
            mVec.push_back(QString("    -Y " + QString::number(qrand()) + " +X " + QString::number(qrand())));
        else if (counter == 10)
            mVec.push_back(QString("#-Y " + QString::number(qrand()) + " +X " + QString::number(qrand()) + "       b         "));
        else
            mVec.push_back(QString("-Y " + QString::number(qrand()) + " +X " + QString::number(qrand())));
    }
    return mVec;
}


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 05, 2014, 16:26
Цитировать
Во всех этих случаях Вам придется немало посуетиться с гордым/крутым "решением в 1 строку" и оно станет не таким уж простым. В то же время тупенький разбор "слово за словом" выдержит эту нагрузку без проблем.

Разбор "слово за словом" при новых условиях придётся модифаить. Как и регексп. Как и фаинд. А изменения не станут проблемой, в принципе, ни в одном из случаев.
Не уверен. Предположим заданы такие правила (на мой взгляд совершенно простые и разумные)

X(Y) - задать абсолютное значение
+X(Y) - добавить к текущему значению
-X(Y) - отнять от текущего значения

Как порешать с regexp?


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 16:28
Как порешать с regexp?
Почитать про регулярные выражения?  ;D


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 05, 2014, 16:32
Почитать про регулярные выражения?  ;D
Так читайте, я ж Вам не запрещаю  :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 16:33
Так читайте, я ж Вам не запрещаю  :)
Я уже почитал, поэтому такие наивные вопросы как у вас у меня и не возникают. :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 16:53
Сделал так, ничего кардинально не изменилось:
Почему, вы рассчитываете, что вокруг "+X " " -Y " пробелы? Может там табуляции? :)
И чем больше будет таких "может" - тем больше вы будете добавлять проверок/условий.
А с регулярками вы просто будете чуть менять правила и то, если понадобиться.
По скорости - есть другие библиотеки с регуляркой, более быстрые чем в Qt. Зато вы получаете прозрачный код, который можно легко расширять с усложнением правил.


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 05, 2014, 17:02
Выражу мысль простую - если формат известен и не меняется, то любое решение с ним справится.

Если у формата имеются допущения и особенности, то простое решение выиграет. Ибо остальные будут являть собой регэксп или аналог и дополнительную обвязку :)

Универсального формата нет и не будет. И добавочные возможности приёма данных в 90% случаях избыточны. Ибо строится всё на формате. Без формата нет программы и нет регэкспа и нет рабочей версии. Профит :) Изменяемый формат = изменение любой программы.

Потому результат должен удовлетворять простым условиям. Если условия не проходят, строка/элемент отбрасываются.


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 05, 2014, 17:04
Цитировать
Может там табуляции?
А разница для кода какая будет? Если данные пришли не корректные - значит не корректные, - дропаем их.

Цитировать
И чем больше будет таких "может" - тем больше вы будете добавлять проверок/условий.
А регулярку и менять не надо! : )

Цитировать
А с регулярками вы просто будете чуть менять правила и то, если понадобиться.
А в коде я добавлю 1-2 дополнительных if`a.

Цитировать
По скорости - есть другие библиотеки с регуляркой, более быстрые чем в Qt.
Речь шла ИМЕННО про Qt. Ну и вряд ли они будут быстрей, чем простая реализация "в лоб".

Цитировать
Зато вы получаете прозрачный код, который можно легко расширять с усложнением правил.
ИМХО код без регулярок куда как прозрачней. И уж если речь зашла о поддержке, то код без регулярок куда проще поддерживать сторонним разработчикам, тем более низкоквалифицированным.

И вообще, в посте ТСа был вопрос как сделать это средствами Qt. Предложенное ТСом решение рабочее, но как мне кажется, не оптимальное. Регулярки конкретно для этой задачи не подходят - скорость в приоритете. Остаётся только решение в лоб, которое, кстати, показало лучшую скорость.

Вместо заключения:
Я не спорю с полезностью и удобность регулярок, но на таких мелких задачах больше подходит решение в лоб. Строго моё мнение : )




Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 17:13
А разница для кода какая будет? Если данные пришли не корректные - значит не корректные, - дропаем их.
А почему они не корректные? Табуляция такой же символ разделитель как и пробел.

А в коде я добавлю 1-2 дополнительных if`a.
Вот-вот. На каждый чих. А потому так в этом погрязните, что сами ничего не сможете разобрать. :)

ИМХО код без регулярок куда как прозрачней.
Это пока все так легко и просто. А теперь представьте, что выдернуть нужно не цифры, а номер телефон и email. Проверить их на валидность и выдернуть. :)

А так можно принять что в файле позиции чисел фиксированы:
-Y 00012 +X 01234
И выдергивать их из строку по точным смещениям: первое число - подстрока 3-7 символ; второе число - подстрока 11-15.
Ну а что, будет еще быстрей. :)

тем более низкоквалифицированным.
А ну тогда да. Про низкоквалифицированных поддержалщиков я уже писал свое мнение на форуме.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 17:14
на таких мелких задачах больше подходит решение в лоб. Строго моё мнение : )
Мелкие задачи имеют свойство сильно укрупняться. :)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 05, 2014, 17:29
"Из пушки по воробьям" ©

Подобное уже встречалось в моей практике. Для 3 классов была создана фабрика классов, сериализация данных через S11n и ноды (что совсем не подходило для данных и приходилось костыли ставить). При том что парсер этого формата и эти классы я переписал за 2 дня. И вместо 1 непонятного и неописуемого класса, используеющего буст и s11n и Qt (описать мог только создатель) появились 3 класса, понятных всем.

PS "Самодокументируемость кода указывает на его простоту и гениальность" ©


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 17:30
"Из пушки по воробьям" ©
Вы сейчас о чем? О регулярках?


Название: Re: Парсинг строки определенного типа
Отправлено: kambala от Май 05, 2014, 17:35
как правило регулярки не использует и ругает тот, кто в них не разобрался :) не так часто бывают случаи где надо выжимать максимальную скорость (счет на миллисекунды).


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 05, 2014, 17:55
Они удобны для заковыристых и масштабных случаев. Когда же формат простой они просто не нужны... (моё мнение ^.^)

К тому же тут имеется факт что поддержка дальнейшая должна тоже знать reg exp'ы.

В целом я выше приводил - все способы хороши, но у региков выше порог и невозможность допущений без костылей.

Но спорить бессмысленно, это уже вопрос к ТСсу - что ему надо :)


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 05, 2014, 18:10
Цитировать
А почему они не корректные? Табуляция такой же символ разделитель как и пробел.
Да, верно. А еще у меня в файлике может быть такой сплиттер "My\npretty$splitter\t\r\n\r\n;amp&". Формат сплиттеров в фале обговаривается стандартом для данного файлика. Иначе представляю как парсились бы пресловутые плэйлисты.

Цитировать
Вот-вот. На каждый чих. А потому так в этом погрязните, что сами ничего не сможете разобрать.
В коде парсера, который парсит заданный формат файла, тяжело не разобратся. Я так пологаю, что даже студены с простыми фаиндами совладают.
 
Цитировать
Это пока все так легко и просто. А теперь представьте, что выдернуть нужно не цифры, а номер телефон и email. Проверить их на валидность и выдернуть.
Здесь вам надо привести алгоритм? Это просто.

Цитировать
А так можно принять что в файле позиции чисел фиксированы:
-Y 00012 +X 01234
И выдергивать их из строку по точным смещениям: первое число - подстрока 3-7 символ; второе число - подстрока 11-15.
Ну а что, будет еще быстрей.
Это самый лучший способ. Но смещений не будет. Т.е. не будет дополнительных нулей.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 18:19
В коде парсера, который парсит заданный формат файла, тяжело не разобратся. Я так пологаю, что даже студены с простыми фаиндами совладают.
Я уже писал, что этот формат прост, но все простое имеет свойство усложняться со временем. :)

Здесь вам надо привести алгоритм? Это просто.
Мне алгоритм не нужен, добавьте к своему парсеру такую возможность.
Например теперь формат такой:
-Y 10     +X    204           \t\t Phone +7-909-909-99-99      EMail progorg@prog.org.ru

Номер телефона может быть с +7, может с 8, а может вообще без этого префикса. Попробуйте телефон с электронкой проверять на валидность. ;) А с регулярками это одна строка, которая их еще и выделит.


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 05, 2014, 18:45
Цитировать
Мне алгоритм не нужен
Цитировать
добавьте к своему парсеру такую возможность

Так всё-таки не нужен или добавить?

Цитировать
Попробуйте телефон с электронкой проверять на валидность.
А это уже другая задача, которую действительно лучше решить регуляркой (я про валидацию мыла и телефона). Валидация выдраных данных - это отдельный функционал. Речь шла о парсе.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 18:56
А это уже другая задача, которую действительно лучше решить регуляркой (я про валидацию мыла и телефона).
Вот это я и пытаюсь донести. В начале пути не всегда видно, что будет в конце. :)
Программа эволюционирует за изменяющимися требованиями. Сейчас нужно просто дергать два числа, через месяц к ним добавиться пару строк, а через год понадобятся телефоны и адреса. Когда нужно перестать подставлять костыли к своему простому решению и перейти на регулярку? :)



Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 05, 2014, 19:01
А это уже другая задача, которую действительно лучше решить регуляркой (я про валидацию мыла и телефона).
Вот это я и пытаюсь донести. В начале пути не всегда видно, что будет в конце. :)
Программа эволюционирует за изменяющимися требованиями. Сейчас нужно просто дергать два числа, через месяц к ним добавиться пару строк, а через год понадобятся телефоны и адреса. Когда нужно перестать подставлять костыли к своему простому решению и перейти на регулярку? :)



В общем и целом - Вы правы. Но с другой стороны ни разу в своих проектах не пользовал регулярку. Тем более, что парсить приходилось либо ini-подобные файлы, либо JSON, либо XML. Я плохой программист, что не использовал регулярки для парса ini-подобных файлов?


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 05, 2014, 19:13
Я плохой программист, что не использовал регулярки для парса ini-подобных файлов?
Ну это просто детский сад. :)
Вовсе нет.


Название: Re: Парсинг строки определенного типа
Отправлено: _OLEGator_ от Май 05, 2014, 20:25
Они удобны для заковыристых и масштабных случаев. Когда же формат простой они просто не нужны... (моё мнение ^.^)

К тому же тут имеется факт что поддержка дальнейшая должна тоже знать reg exp'ы.

В целом я выше приводил - все способы хороши, но у региков выше порог и невозможность допущений без костылей.

Но спорить бессмысленно, это уже вопрос к ТСсу - что ему надо :)

О чем спор?
Если программист ноет о том, что ему сложно разобраться в регулярных выражениях - грош цена такому программисту, не ту профессию он выбрал.
Программист должен постоянно развиваться и использовать не только базовые возможности языка, застяв в if'ах.


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 05, 2014, 21:08
Во-первых, код приведённый k0p4ем весьма наивен..

Давайте взглянем на всё это более трезво.. (хотя я сейчас и после юбилея своей бабушки, но всё же)

И так, мы хотим распарсить некий, достаточно детский формат данных.. Причём, так, что бы мы имели информацию о том, что пошло не так..
Если, например, в какой то строке что то не соответствует правилам игры, то код  k0p4а просто пролетает..

Вот вариант того (народный метод в лоб), что мне сейчас удалось написать на коленке:
Код
C++ (Qt)
#include <QString>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QVector>
#include <QPoint>
#include <QRegExp>
#include <QList>
 
bool extractData(const QString & str, int & x, int & y)
{
   static const QString prefixX = "+X";
   static const QString prefixY = "-Y";
   static const QChar space = ' ';
 
 
   if (!str.startsWith(prefixY))
   {
       qDebug() << "1 ;(";
       return false;
   }
 
   int n = prefixY.size();
   if (str[n] != space)
   {
       qDebug() << "2 ;(";
       return false;
   }
 
   if (++n == str.size())
   {
       qDebug() << "3 ;(";
       return false;
   }
 
   int m = str.indexOf(space, n);
   if (m == -1)
   {
       qDebug() << "4 ;(";
       return false;
   }
 
   bool ok = false;
   y = str.mid(n, m-n).toInt(&ok);
   if (!ok)
   {
       qDebug() << "5 ;(";
       return false;
   }
 
   if (str[m] != space)
   {
       qDebug() << "6 ;(";
       return false;
   }
 
   n = str.indexOf(prefixX, ++m);
 
   if (n != m)
   {
       qDebug() << "7 ;(";
       return false;
   }
 
   n += prefixX.size();
 
   if (n == str.size())
   {
       qDebug() << "8 ;(";
       return false;
   }
 
   x = str.mid(++n, str.size()).toInt(&ok);
 
   if (!ok)
   {
       qDebug() << "9 ;(";
       return false;
   }
 
   return true;
 
}
 
Это тот "простейший метод" сделать  это прогоняясь по строке. Обратите внимание на число проверок (необходимых), для того, что бы в итоге не получить полную чушь.

И это только из предположения, что "скипперами" являются только одиночные пробелы! Если, например, в правилах (внезапно) появилось условие на неограниченность пробелов, или наличие табов, то придётся руками править весь приведённый код выше(
Это по вашему проще, чем пару движениями изменить регулярку? Ну тогда, знаете..

Во-вторых, все эти вопли о производительности здесь лишены смысла.. Да, в данном случае, решение в лоб, работает быстрее.. Но.. Но не более чем в три раза.. Это даже не порядок величины! Стоит ли ради этого городить весь этот костыльный вариант?
Вот как выглядит решение с QRegExp^
Код
C++ (Qt)
template <class Container>
void readData_QRegExManner(const QString & fileName, Container & v)
{
   QFile file(fileName);
   if (!file.open(QIODevice::ReadOnly))
   {
       qDebug() << "Error opening file";
       return;
   }
 
   QTextStream stream(&file);
 
   QString str = stream.readAll();
 
   QRegExp regex("\\-Y (\\d+) \\+X (\\d+)");
   regex.setMinimal(true);
 
   int pos = 0;
   while ((pos = regex.indexIn(str, pos)) != -1)
   {
       int y = regex.cap(1).toInt();
       int x = regex.cap(2).toInt();
       v.append(QPoint(x, y));
       pos += regex.matchedLength();
   }
 
 
}
 
Всё! Это решение гораздо более устойчивее к начальным условиям. Потребуется добавить что то сверх формата, то в RegExp это делается заменой только одной строки.. А что будет в "народном"варианте в лоб? Код как минимум увеличится в разы..
И не говорите мне, что сопровождать эту кашу будет легче..  Напротив(

И в-третьих, если уж вы так вопите о производительности, то банальный boost::xpressive сделает всех..
А если кто то так заботиться о обработке ошибок и т.п.. то boost::spirit предоставляет гибкие решения и этой проблемы.
Оставаясь на порядок более гибким, понятным и производительным решением..)

Лично с моей точки зрения, решение"построчного пробега" - это последнее, что пришло бы мне в голову( В общем случаее и в частности..  




Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 05, 2014, 22:30
to _OLEGator_: Один раз мы переписывали программу из-за того, что все программисты "поддержки" в фирме умели программировать только на... паскале. Какие там рег экспы :)
Суть сообщения которую я хочу до вас донести - высокие стандарты это гуд, развиваться надо, но остались ещё люди, пишушие x= x+1; x=x+2; x=x+3; x=x+n вместо цикла :)

PS ну и читабельность кода. Мб у меня мало опыта, но представить по регулярке исходное выражение я не могу, особенно если группы используются.


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 05, 2014, 23:33
to _OLEGator_: Один раз мы переписывали программу из-за того, что все программисты "поддержки" в фирме умели программировать только на... паскале. Какие там рег экспы :)
Суть сообщения которую я хочу до вас донести - высокие стандарты это гуд, развиваться надо, но остались ещё люди, пишушие x= x+1; x=x+2; x=x+3; x=x+n вместо цикла :)

PS ну и читабельность кода. Мб у меня мало опыта, но представить по регулярке исходное выражение я не могу, особенно если группы используются.

Угу.. Вот это то и печально( Печально, когда код пишется для таких "профессианалов" которые только на паскале и умеют..
И то, что остались ещё люди, пишущие x = x + 1 и т.п. никак не оправдывает вашу политику фирмы.. А напротив(
А в итоге имеем дегродированный код, который если что, то лучше переписать с нуля, чем поддерживать в дальнейшем( 


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 05, 2014, 23:43
Ммм... зато после ядрёной войны этот код сможет восстановить и поправить и поддержать любой самоучка с книжкой по С++ :) Так что во всём свои плюсы.

PS я не вижу "где плохо". Простота формата = простоте кода = простота поддержки. Я вижу будущее за понятным кодом, аналогом Qt. Где со строкой мы работаем как со строкой, а не копируем области памяти в области памяти и представляем всё массивом.

PPS да, заглядывая во внутренности Qt, я не увидел там шаблонов, страшных конструкций и прочего. Всё просто. Назовёте код Qt плохим?


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 05, 2014, 23:49
Ммм... зато после ядрёной войны этот код сможет восстановить и поправить и поддержать любой самоучка с книжкой по С++ :) Так что во всём свои плюсы.

PS я не вижу "где плохо". Простота формата = простоте кода = простота поддержки. Я вижу будущее за понятным кодом, аналогом Qt. Где со строкой мы работаем как со строкой, а не копируем области памяти в области памяти и представляем всё массивом.

PPS да, заглядывая во внутренности Qt, я не увидел там шаблонов, страшных конструкций и прочего. Всё просто. Назовёте код Qt плохим?
Т.е. я правильно понял, что для вас этот код:
Код
C++ (Qt)
bool extractData(const QString & str, int & x, int & y)
{
   static const QString prefixX = "+X";
   static const QString prefixY = "-Y";
   static const QChar space = ' ';
 
 
   if (!str.startsWith(prefixY))
   {
       qDebug() << "1 ;(";
       return false;
   }
 
   int n = prefixY.size();
   if (str[n] != space)
   {
       qDebug() << "2 ;(";
       return false;
   }
 
   if (++n == str.size())
   {
       qDebug() << "3 ;(";
       return false;
   }
 
   int m = str.indexOf(space, n);
   if (m == -1)
   {
       qDebug() << "4 ;(";
       return false;
   }
 
   bool ok = false;
   y = str.mid(n, m-n).toInt(&ok);
   if (!ok)
   {
       qDebug() << "5 ;(";
       return false;
   }
 
   if (str[m] != space)
   {
       qDebug() << "6 ;(";
       return false;
   }
 
   n = str.indexOf(prefixX, ++m);
 
   if (n != m)
   {
       qDebug() << "7 ;(";
       return false;
   }
 
   n += prefixX.size();
 
   if (n == str.size())
   {
       qDebug() << "8 ;(";
       return false;
   }
 
   x = str.mid(++n, str.size()).toInt(&ok);
 
   if (!ok)
   {
       qDebug() << "9 ;(";
       return false;
   }
 
   return true;
 
}
 
более предпочтительнее для дальнейшей поддержки?
Не смотря на те аргументы, что я показал всю костыльность этого подхода?

Ну тогда у меня вопросов больше нет(

И кстатии, вы уверены, что после ядерной войны кому то вообще придёт в голову восстанавливать этот бред?
Хотя, конечно, ничего другого, кроме говнокода (и ремесленников средней руки), после ядерной войны не останется..


Название: Re: Парсинг строки определенного типа
Отправлено: _OLEGator_ от Май 06, 2014, 09:31
Простота формата = простоте кода = простота поддержки.

Не согласен. Спагетти-код поддерживать невозможно.
А быдло программисты должны мучиться, нельзя писать код с расчетом на них.


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 06, 2014, 11:36
Вот вариант того (народный метод в лоб), что мне сейчас удалось написать на коленке:
...
Это тот "простейший метод" сделать  это прогоняясь по строке. Обратите внимание на число проверок (необходимых), для того, что бы в итоге не получить полную чушь.
Т.е. при отсутствии чудесных средств (которыми программист обязан владеть) надо было писать как Вы исполнили "на коленке"? (тот код даже неудобно цитировать). Неправда, можно было написать нормально, напр
Код
C++ (Qt)
int x, y;
QString phone, mail;
static const QString prefixX = "+X";
static const QString prefixY = "-Y";
static const QString str_Phone = "Phone";
static const QString str_Mail = "Mail";
 
try {
ExpectWord(src, prefixX);
x = ExpectInt(src);
 
ExpectWord(src, prefixY);
y = ExpectInt(src);
 
ExpectWord(src, str_Phone);
phone = NextWord(src);
 
ExpectWord(src, str_Mail);
mail = NextWord(src);
}
catch (...) {
..
}
- скорости здесь можно выжать очень хорошую
- контроль ошибок полный
- читабельность отличная, вообще нет переходов вверх (спагетти)
- поддержка: ну думаю что делают вызовы - всем понятно по их именам

Основное возражение: Кааак??? Это я должен еще писать какие-то велосипеды??? (ExpectWord, NextWord). Да, решение с QRegExp намного короче. Но ведь это достигнуто за счет отсутствия всякого контроля. Типа "нашла - хорошо, не нашла - ну и ладно".  

А если кто то так заботиться о обработке ошибок и т.п..
Да, заботится, и не надо тут "делать одолжение", контроль ошибок - это часть работы.

то boost::spirit предоставляет гибкие решения и этой проблемы. Оставаясь на порядок более гибким, понятным и производительным решением..)
Позвольте, но ведь Вы только что воспевали регулярку! А теперь выходит надо применять совсем др инструментарий, и затратить не один день на его изучение. Как же так ???

А может все куда проще - руками делать не умеем, вот и ищем тулзы чтобы прикрыться  :)


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 06, 2014, 11:54
Цитировать
Позвольте, но ведь Вы только что воспевали регулярку! А теперь выходит надо применять совсем др инструментарий, и затратить не один день на его изучение. Как же так
Спирит я привёл как пример инструмента, где уже реализован механизм за контролем ошибок (прямо из коробки)

В чём проблема реализовать контроль над ошибками используя regex? Также читаете построчно файл и к каждой строке применяете регулярку.. Если не проходит, то выкидываем эту строку в логгер, который знает что с ней делать.. Всё.

Цитировать
А может все куда проще - руками делать не умеем, вот и ищем тулзы чтобы прикрыться
Аха.. Зато я смотрю, другие прекрасно умеют)


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 06, 2014, 12:14
Во-первых, код приведённый m_ax`ом весьма странный.
Давайте разберём по порядку и сравним мой код, и код Макса.

Итак,
1. Почему мы матчим не "-Y " и " +X " стринги, а отдельно "-Y", "+X" и пробелы? В формате файла четко указано что после (в случае +X еще и перед) выражением идут пробелы. Какой смысл их проверять? Если мы не смогли сматчить  "-Y " и " +X ", то значит формат уже не верный. Какова причина возврата стольких ошибок? Просто сделать спагетти? : )
Код:
    if (!str.startsWith(prefixY))
    {
        qDebug() << "1 ;(";
        return false;
    }
 
    int n = prefixY.size();
    if (str[n] != space)
    {
        qDebug() << "2 ;(";
        return false;
    }
 
    // Очень порадовала проверка : )
    if (++n == str.size())
    {
        qDebug() << "3 ;(";
        return false;
    }
 
    int m = str.indexOf(space, n);
    if (m == -1)
    {
        qDebug() << "4 ;(";
        return false;
    }

Заменяется на
Код:
 
        if (!line.startsWith("-Y "))
            continue;

2. Каюсь, забыл бул на toInt().
Код:
bool ok = false;
    y = str.mid(n, m-n).toInt(&ok);
    if (!ok)
    {
        qDebug() << "5 ;(";
        return false;
    }

3. Так же заменяется
Код:
    if (str[m] != space)
    {
        qDebug() << "6 ;(";
        return false;
    }
 
    n = str.indexOf(prefixX, ++m);
 
    if (n != m)
    {
        qDebug() << "7 ;(";
        return false;
    }
 
    n += prefixX.size();
 
    if (n == str.size())
    {
        qDebug() << "8 ;(";
        return false;
    }

На

Код:
       // Handle error.
        if ((posX = line.indexOf(" +X ")) == -1)
            continue;

4. Забыл бул, как и выше : )
5. Если на то пошло, и вы так дотошно проверяете несоответствие формата для парса в лоб, что бы сообщить конкретную позицию, то почему я не вижу ни одной такой же проверки в РегЕкспе.
6.
Цитировать
Это тот "простейший метод" сделать  это прогоняясь по строке. Обратите внимание на число проверок (необходимых), для того, что бы в итоге не получить полную чушь.
Полная чушь.
7.
Цитировать
И это только из предположения, что "скипперами" являются только одиночные пробелы! Если, например, в правилах (внезапно) появилось условие на неограниченность пробелов, или наличие табов, то придётся руками править весь приведённый код выше(
Как будут вести себя регекспы? Или вы сравниваете затраты на поддержку кода?
8.
Цитировать
Это по вашему проще, чем пару движениями изменить регулярку? Ну тогда, знаете..
Какбе, я ж уже писал Олду, что я целиком и полностью за регулярки, а еще лучше, спирит. Но конкретно для поставленной задачи ТСа лучше решения в лоб - нет. Я это аргументировал, провёл замеры и тд. Очень похоже на то, что вы пытаетесь запихнуть регулярки туда, где они совсем и не нужны, аргументируя это расширяемостью.
9.
Цитировать
Во-вторых, все эти вопли о производительности здесь лишены смысла.. Да, в данном случае, решение в лоб, работает быстрее.. Но.. Но не более чем в три раза.. Это даже не порядок величины! Стоит ли ради этого городить весь этот костыльный вариант?
Скажите, а вы когда нибудь писали под embedded? А сколько стоит повышение производительности крупных проектов хотя-бы на 10%? А если будет стоять задача распарсить огромные куски данных?
10.
Цитировать
Всё! Это решение гораздо более устойчивее к начальным условиям. Потребуется добавить что то сверх формата, то в RegExp это делается заменой только одной строки.. А что будет в "народном"варианте в лоб? Код как минимум увеличится в разы..
И не говорите мне, что сопровождать эту кашу будет легче..  Напротив(
Нет, ну если из "народной лапши" так же выпилить Ваши проверки - то сопровождать будет легче в разы.
11.
Цитировать
А если кто то так заботиться о обработке ошибок и т.п.. то boost::spirit предоставляет гибкие решения и этой проблемы.
Оставаясь на порядок более гибким, понятным и производительным решением..)
Вы целиком и полность правы.
12.
Цитировать
Лично с моей точки зрения, решение"построчного пробега" - это последнее, что пришло бы мне в голову( В общем случаее и в частности..   
Досадно : )

_OLEGator_, Вы наверняка работаете в команде до 5 человек, да? )



Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 06, 2014, 12:14
В чём проблема реализовать контроль над ошибками используя regex?
Проблема в желании низкоквалифицированных программистов найти оправдание своей не компетенции, для этого придумываются всяческие наивные доводы. :)

А код какой стройный :)
Код
C++ (Qt)
int x, y;
QString phone, mail;
static const QString prefixX = "+X";
static const QString prefixY = "-Y";
static const QString str_Phone = "Phone";
static const QString str_Mail = "Mail";
 
try {
ExpectWord(src, prefixX);
x = ExpectInt(src);
 
ExpectWord(src, prefixY);
y = ExpectInt(src);
 
ExpectWord(src, str_Phone);
phone = NextWord(src);
 
ExpectWord(src, str_Mail);
mail = NextWord(src);
}
catch (...) {
..
}

Для чего столько было программировать, можно же было просто написать так и все: :)
Код
C++ (Qt)
bool super_parser( int &x, int &y, string &phone, string &email );
 

Вот и все решение. А то накодили там. :)
Да еще исключения туда для чего-то добавили и это в Qt. А что с этим будет делать вахтерша баба Маша после ядерной войны? А? :)


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 06, 2014, 12:25
В чём проблема реализовать контроль над ошибками используя regex?
Проблема в желании низкоквалифицированных программистов найти оправдание своей не компетенции, для этого придумываются всяческие наивные доводы. :)

А код какой стройный :)
Код
C++ (Qt)
int x, y;
QString phone, mail;
static const QString prefixX = "+X";
static const QString prefixY = "-Y";
static const QString str_Phone = "Phone";
static const QString str_Mail = "Mail";
 
try {
ExpectWord(src, prefixX);
x = ExpectInt(src);
 
ExpectWord(src, prefixY);
y = ExpectInt(src);
 
ExpectWord(src, str_Phone);
phone = NextWord(src);
 
ExpectWord(src, str_Mail);
mail = NextWord(src);
}
catch (...) {
..
}

Для чего столько было программировать, можно же было просто написать так и все: :)
Код
C++ (Qt)
bool super_parser( int &x, int &y, string &phone, string &email );
 

Вот и все решение. А то накодили там. :)
Да еще исключения туда для чего-то добавили и это в Qt. А что с этим будет делать вахтерша баба Маша после ядерной войны? А? :)


Похоже, что Вы меня не услышали : ) Вобщем, как и Макс. Вы постоянно отводите тему в сторону готовые решения против велосипедов. Очевидно, что лучше использовать готовые решения. И я, в частности, для общих случаев использую готовые решения (по мере возможности : ) ). В частных случаях лучше использовать велосипеды. Например, если стандарт файла уже принят и менятся не будет - лучше использовать решение в лоб. Так как его (с моей точки зрения, конечно же) будет легче поддерживать и оно будет производительней, чем готовое универсальное решение. Велосипед, заточенный под конкретную задачу будет всегда быстрей, чем готовое универсальное решение.
И не надо думать, что все кто не используют Ваши инструменты глупее Вас или просто низкоквалифицированные. Это заблуждение, ящитаю.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 06, 2014, 12:30
Похоже, что Вы меня не услышали : )
Нет-нет. Мой ответ адресован одному "профессионалу", который считает, что чем меньше программист знает, тем он круче. :)
Не принимайте написанное на свой счет. ;)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 06, 2014, 12:40
Вы постоянно отводите тему в сторону готовые решения против велосипедов.
Неправильно вы понимаете. :)
Эта тема продолжение целой серии обсуждений, поэтому не стоит по моим ответам только в ней, судить о моем отношении к велосипедам.
Мы все постоянно пишем велосипеды, если бы были готовые решения на все, мы бы давно были не нужны.
Когда же по моему оправдан велосипед. Мы написали программу, запустили профайлер и поняли, что основные тормоза вызывают такие-то решения. Если для программы жизненно важно ускорение в этих местах, то я буду писать свой велосипед. Причем я вначале изучу эту область и посмотрю на другие решения, которые могут помочь в этом. До этого я не вижу смысла в велосипедах, особенно при работе в больших командах. Регулярки это практически стандарт, и другому программисту будет проще разобраться с ними, чем с сложным велосипедом другого (да еще и низкоквалифицированного) программиста.


И не надо думать, что все кто не используют Ваши инструменты глупее Вас или просто низкоквалифицированные.
Сейчас не идет речь о "Ваших" инструментах, идет разговор о том, что отвергаются любые готовые решения и предлагается писать свой велосипед. А причины этого высасываются из пальца: ожидание того, что какой-то инструмент с этим не справиться (хотя если почитать документацию на инструмент, то такие впечатления сразу исчезнут); сложность для всех в изучении какого-то инструмента (хотя любой программист С++ должен спокойно работать с boost, не говоря уже про std); разговоры о поддержке проекта в дальнейшем вахтершей бабой Машей (поэтому код нужно писать, что бы она его понимала) и других наивных причин. :)


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 06, 2014, 13:09
Old, понял, извиняюсь : )
Цитировать
о том, что отвергаются любые готовые решения и предлагается писать свой велосипед.
Я вовсе не отвергаю готовые решения. Наоборот, для большинства задач так и надо делать. Но ведь есть и частные случаи, где, как мне кажется, лучше велосипеды (ну вот, кажется мы поехали по кругу :Р) : ) Для частных случаев, когда всё полностью известно (формат), не предвидятся изменения и можно сделать быстрее (и как по мне, так более лёгкое в поддержке), чем готовое решение : )
Я пытаюсь донести мысль о частных случаях, для которых общее решение избыточно. Например, как случай с задачей ТСа (с чего и начался спор).
Но и Вас я тоже понял, легче поддерживать (для хороших спецов, как правило), больше гибкость. Удобство готовых решений, за которое, как правило, приходится платить скоростью.


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 06, 2014, 13:20
Это несколько из http://ru.wikipedia.org/wiki/%D0%90%D0%BD%D1%82%D0%B8%D0%BF%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD.

Собственно тут нужна золотая середина.

К тому же изречение что решение в лоб - "спагетти код", в корне неверно. Спагетти код это запутанный код, а в приведённых кодах выполнение идёт последовательно и даже последний человек. еле умеющий читать может назвать порядок выполнения :D


Название: Re: Парсинг строки определенного типа
Отправлено: _OLEGator_ от Май 06, 2014, 13:30
_OLEGator_, Вы наверняка работаете в команде до 5 человек, да? )

Не принимайте мои комментарии на свой счет.
Это было сказано в контексте, что регулярки это сложно, кто-то может их не знать.

В конечном счете выбор инструмента производится исходя из поставленной задачи.
Если нужна производительность и регулярки не подходят - то да, ищется другое решение.


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 06, 2014, 13:38
to k0p4

Долго отвечать на все ваши пункты, отвечу на некоторые ключевые..

Цитировать
Как будут вести себя регекспы? Или вы сравниваете затраты на поддержку кода?
Регексп изменится минимально (одно движение), в отличии от решения в лоб..
Производительность от этого также не пострадает)

Цитировать
Но конкретно для поставленной задачи ТСа лучше решения в лоб - нет. Я это аргументировал, провёл замеры и тд. Очень похоже на то, что вы пытаетесь запихнуть регулярки туда, где они совсем и не нужны, аргументируя это расширяемостью.
Это глупости) Если для вас единственный критерий - это производительность, то замечу, что вариант на xpressive раза в два быстрее)

Цитировать
Скажите, а вы когда нибудь писали под embedded? А сколько стоит повышение производительности крупных проектов хотя-бы на 10%? А если будет стоять задача распарсить огромные куски данных?
Под embedded не писал, но приходится иногда писать числодробилки, где производительность - на первом месте)

Привожу маленький проектик с тремя реализациями парсера: xpressive, QRegExp и вариант ТС
Результаты трёх замеров такие:
Код
Bash
test Veres Manner, time (ms) :  1830
 
test QRegEx Manner, time (ms) :  4501
 
test XPressive Manner, time (ms) :  1246
 
 
------------------------------------------------------------------------
 
test Veres Manner, time (ms) :  1715
 
test QRegEx Manner, time (ms) :  4512
 
test XPressive Manner, time (ms) :  1263
 
 
------------------------------------------------------------------------
 
test Veres Manner, time (ms) :  1819
 
test QRegEx Manner, time (ms) :  4504
 
test XPressive Manner, time (ms) :  1298
 
 

Вод сами исходники:
Код
C++ (Qt)
#include <iostream>
#include <fstream>
#include <sstream>
#include <chrono>
#include <list>
 
 
#include <boost/xpressive/xpressive.hpp>
 
 
#include <QString>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QVector>
#include <QPoint>
#include <QRegExp>
#include <QList>
 
bool extractData(const QString & str, int & x, int & y)
{
   static const QString prefixX = "+X";
   static const QString prefixY = "-Y";
   static const QChar space = ' ';
 
 
   if (!str.startsWith(prefixY))
   {
       qDebug() << "1 ;(";
       return false;
   }
 
   int n = prefixY.size();
   if (str[n] != space)
   {
       qDebug() << "2 ;(";
       return false;
   }
 
   if (++n == str.size())
   {
       qDebug() << "3 ;(";
       return false;
   }
 
   int m = str.indexOf(space, n);
   if (m == -1)
   {
       qDebug() << "4 ;(";
       return false;
   }
 
   bool ok = false;
   y = str.mid(n, m-n).toInt(&ok);
   if (!ok)
   {
       qDebug() << "5 ;(";
       return false;
   }
 
   if (str[m] != space)
   {
       qDebug() << "6 ;(";
       return false;
   }
 
   n = str.indexOf(prefixX, ++m);
 
   if (n != m)
   {
       qDebug() << "7 ;(";
       return false;
   }
 
   n += prefixX.size();
 
   if (n == str.size())
   {
       qDebug() << "8 ;(";
       return false;
   }
 
   x = str.mid(++n, str.size()).toInt(&ok);
 
   if (!ok)
   {
       qDebug() << "9 ;(";
       return false;
   }
 
   return true;
 
}
 
template <class Container>
void readData_VeresManner(const QString & fileName, Container & v)
{
   QFile file(fileName);
   if (!file.open(QIODevice::ReadOnly))
   {
       qDebug() << "Error opening file";
       return;
   }
 
   QTextStream stream(&file);
 
   while (!stream.atEnd())
   {
       QString str = stream.readLine();
       int x, y;
       if (extractData(str, x, y))
       {
           v.append(QPoint(x, y));
       }
   }
}
 
template <class Container>
void readData_QRegExManner(const QString & fileName, Container & v)
{
   QFile file(fileName);
   if (!file.open(QIODevice::ReadOnly))
   {
       qDebug() << "Error opening file";
       return;
   }
 
   QTextStream stream(&file);
 
   QString str = stream.readAll();
 
   QRegExp regex("\\-Y (\\d+) \\+X (\\d+)");
   regex.setMinimal(true);
 
   int pos = 0;
   while ((pos = regex.indexIn(str, pos)) != -1)
   {
       int y = regex.cap(1).toInt();
       int x = regex.cap(2).toInt();
       v.append(QPoint(x, y));
       pos += regex.matchedLength();
   }
 
}
 
template <class Container>
void readData_XPressiveManner(const char * fileName, Container & v)
{
   using namespace boost::xpressive;
 
   std::ifstream in(fileName);
   if (!in.is_open())
   {
       qDebug() << "Error opening file";
       return;
   }
 
   std::ostringstream oss;
   oss << in.rdbuf();
 
   std::string buff = oss.str();
 
   sregex expr = as_xpr("-Y") >> +space >> (s1 = +_d) >> +space >> as_xpr("+X") >> +space >> (s2 = +_d);
 
   sregex_iterator it(buff.cbegin(), buff.cend(), expr);
   sregex_iterator end;
 
   for (; it != end; ++it)
   {
       int x = std::stoi((*it)[2]);
       int y = std::stoi((*it)[1]);
       v.push_back(std::pair<int, int>(x, y));
   }
}
 
 
void generateData(const QString & fileName, int size)
{
   QFile file(fileName);
   if (!file.open(QIODevice::WriteOnly))
   {
       qDebug() << "Error opening file";
       return;
   }
 
   QTextStream stream(&file);
 
   static const QString prefixX = "+X";
   static const QString prefixY = "-Y";
   static const QChar space = ' ';
   static const int max = 10000;
 
   for (int i = 0; i  < size; ++i)
   {
       int x = qrand() % max;
       int y = qrand() % max;
       stream << prefixY << space << y << space << prefixX << space << x << endl;
   }
}
 
 
 
int main()
{
   static const int dataSize = 1000000;
 
   QString fileName = "test_data.txt";
   generateData(fileName, dataSize);
 
   QList<QPoint> v1;
   QList<QPoint> v2;
 
   auto start = std::chrono::high_resolution_clock::now();
   readData_VeresManner(fileName, v1);
   auto stop = std::chrono::high_resolution_clock::now();
   auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count();
 
   qDebug() << "test Veres Manner, time (ms) : " << duration;
   qDebug() << v1.size();
 
 
   start = std::chrono::high_resolution_clock::now();
   readData_QRegExManner(fileName, v2);
   stop = std::chrono::high_resolution_clock::now();
   duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count();
 
   qDebug() << "test QRegEx Manner, time (ms) : " << duration;
   qDebug() << v2.size();
 
   std::list<std::pair<int, int>> v3;
   start = std::chrono::high_resolution_clock::now();
   readData_XPressiveManner(fileName.toStdString().c_str(), v3);
   stop = std::chrono::high_resolution_clock::now();
   duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count();
 
   qDebug() << "test XPressive Manner, time (ms) : " << duration;
   qDebug() << v3.size();
 
 
 
   return 0;
}
 
 

И того, по удобству, скорости, гибкости xpressive здесь весьма хорош) Если в дальнейшим формат слегка измениться (а хорошие архитектурные решения должны быть устойчивы к возможным начальным малым изменениям) с регекспом мы потратим минимум усилий..
В коде ТС придётся разбираться, а возможно и переписывать( (давайте представим, что код попал к другому программисту) чтобы среагировать на эти малые изменения.. И не надо говорить, что формат жёстко задан и т.д. и т.п..



  
  

  


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 06, 2014, 13:51
m_ax,
Експрессив идеально зашёл. Как по мне - вне конкуренции. : )
По остальным пунктам можно спорить бесконечно.
А так же стоит вспомнить первый пост:
Цитировать
Вопрос: как это сделать средствами Qt не прибегая к sscanf и желательно без регулярных выражений?

_OLEGator_, Извините : )


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 07, 2014, 09:50
Сейчас не идет речь о "Ваших" инструментах, идет разговор о том, что отвергаются любые готовые решения и предлагается писать свой велосипед. А причины этого высасываются из пальца: ожидание того, что какой-то инструмент с этим не справиться (хотя если почитать документацию на инструмент, то такие впечатления сразу исчезнут); сложность для всех в изучении какого-то инструмента (хотя любой программист С++ должен спокойно работать с boost, не говоря уже про std); разговоры о поддержке проекта в дальнейшем вахтершей бабой Машей (поэтому код нужно писать, что бы она его понимала) и других наивных причин. :)
Вернемся к первоначальному решению ТС. Чем оно плохо? Да ничем. Какое время требуется для его реализации? Ну минут 10-15 (с расписыванием всех ошибок). Допустим (всего лишь допустим) не устраивает скорость - и это можно легко решить. Т.е. "цена вопроса" копеечная.

И тут знатоки впадают в справедливый гнев :) Низкоквалифицированный непрофессионал! (знатоки редко умеют вести себя прилично). Оказывается надо было как-то так
bool super_parser( int &x, int &y, string &phone, string &email );
sregex expr = as_xpr("-Y") >> +space >> (s1 = +_d) >> +space >> as_xpr("+X") >> +space >> (s2 = +_d);
Так вот, на мой взгляд, это совершенно непрофессионально. Если вопрос решается за 15 мин - его надо просто решать, а не тратить день на чтение/изучение. Да, может быть что изучив/почитав можно сделать за минуту  (и даже меньше), но с точки зрения текущей конкретной задачи это не оправдывает себя. Разница в десяток-другой строк не является каким-то "показателем класса", здесь любое решение приемлемо если оно реализовано грамотно и аккуратно. Да-да, часто любитель знает гораздо больше профессионала  :)

А мотив обвинения прекрасно понятен: "оправдать выученное" :)  Ведь тратилось время, чего-то там читалось, а тут оказывается(?) можно и без этого... Да не может такого быть! И.т.п.  :)



Название: Re: Парсинг строки определенного типа
Отправлено: _OLEGator_ от Май 07, 2014, 10:34
Если вопрос решается за 15 мин - его надо просто решать, а не тратить день на чтение/изучение. Да, может быть что изучив/почитав можно сделать за минуту  (и даже меньше), но с точки зрения текущей конкретной задачи это не оправдывает себя.

Да-да, часто любитель знает гораздо больше профессионала

"оправдать выученное"

Толсто троллишь. Не профессионально.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 07, 2014, 11:17
Так а где решение то, с телефоном и емейлом? Не получилось? :)
Вы его с навороченым QString будете делать день, а с регулярками добавляется за несколько минут.

По поводу времени написания и изучения. Если один раз потратить время и разобраться, то дальше можно за 5 минут делать хорошие расширяемый решения. Т.е. день разбираться нужно исключительно вам из-за вашего не знания. :)

Нет, мотив критики оправдать не знание. Пока пишешь сам для себя в одно лицо и заказчик готов терять время и деньги, то можно велосипедить хоть все время.

И конечно нет смысла оправдывать знание. Зная что-то это знание легко не применять, а вот не имея знания - применить его невозможно. :)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 07, 2014, 12:23
Синдром золотого молотка в действии. Когда он в руках, любая вещь кажется гвоздём. Это с одной стороны.

С другой стороны мы строим велосипеды. Но мы строим простые и понятные каждому - сел и поехал.

PS любое простое решение с проверками на QString'e я напишу за день максимум, даже не имея под рукой компьютера. А вот проверить работу regExp'ов я не смогу :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 07, 2014, 13:16
Да вы не только проверить, вы и написать регулярное выражение не сможете. :)
К радости это не является проблемой регулярных выражений. Так же как и всего другого, что вам не удалось освоить. ;)

И никакого золотого молотка здесь нет, регулярку именно для таких задач и придумали. Это её дом родной. :)


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 07, 2014, 13:43
Зная что-то это знание легко не применять,
Данная нитка демонстрирует как раз обратное: "Зная что-то это знание невозможно не применять!". При этом Вы с Олегом проявляете прямо-таки религиозный фанатизм (постоянно сбиваясь на грубость). Заклеймим позором тех кто не знает регулярок! Грош им цена! :) А между тем примерчик ТС можно делать как угодно - и от этого никто не пострадает.

Так а где решение то, с телефоном и емейлом? Не получилось? Улыбающийся
Вы его с навороченым QString будете делать день, а с регулярками добавляется за несколько минут....
...
Пока пишешь сам для себя в одно лицо и заказчик готов терять время и деньги, то можно велосипедить хоть все время.
Телефон и мейл я сразу и добавил. Зачем пугать "как ужасна жизнь без регулярки! Поддерживать эту кашу невозможно!" и.т.п. Вы же прекрасно понимаете что это неправда (мягко говоря). Это будет просто немного длиннее, но все там прекрасно получается. А вот если без регулярки жить не может и каша получается - это хреново.

Про заказчика, время и деньги: не платит никто за парсинг (во всяком случае мне), это всего лишь небольшая деталь задачи, экономия на ней не имеет смысла. А 99% времени уходит на совсем др вещи. Ну напр
Цитировать
есть 2 треугольника на плоскости, посчитать их пересечение в виде неск новых треугольников
Ну вот и закончились "популярные знания" и то что считается "техникой", бум велосипедить или как?  :)  
  


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 07, 2014, 13:50
Вот именно что будет длиннее и больше времени потрачено на реализацию каких то велосипедных парсеров, вместо решения задач заказчика. Вы тратите его время и деньги на решение кучи мелких подзадач, для которых решение уже давно найдено, вместо решения задач которые нужны заказчику.
С треугольниками вы тоже сели в лужу? Да, это не финдреплейсы писать на QString. :) И сортировки что-то не параллелятся. Там тоже не очень велосипедится...? Даже телефонные номера не парсятся. Зато два инта из строки достать, это вы первые. :)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 07, 2014, 14:04
Old заметьте - вы перешли на личности и начали грубить странице на второй этой темы. У вас просто нет других аргументов :D

PS я напишу регулярку, даже могу её применить, но смысл? Я не использую и 1% её возможностей в этой задаче :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 07, 2014, 14:10
Old заметьте - вы перешли на личности и начали грубить странице на второй этой темы.
Боже, покажите где? Я не припомню не грубости, не переходов на личности.
Я понял, вы считаете грубостью и переходом на личности мою просьбу доказать ваши слова вашим же кодом? :) Дааа, это я перешел грань.  ;D

У вас просто нет других аргументов :D
Аргументы все выше. Попробуйте их оспорить. ;)

Я не использую и 1% её возможностей в этой задаче :)
Ну конечно. :)
Задача немного изменилась, добавились телефоны и емейлы. Что то пока не один велосипедист не рискнул это завелосипедить. :)


Название: Re: Парсинг строки определенного типа
Отправлено: _OLEGator_ от Май 08, 2014, 09:25
Это холивар.
Нужно применять уже готовые и обкатанные решения, в которых предусмотрена расширяемость и универсальность, в отличие от узкоспециализированных велосипедов.
И ваш велосипед нельзя использовать повторно, какие в нем плюшки?
Не понимаю, почему тогда вы не пишете на голом C++, stl. Зачем используете QString?


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 09:35
Не понимаю, почему тогда вы не пишете на голом C++, stl. Зачем используете QString?
Потому что с QString удалось разобраться, поэтому его используют во всех местах.
А вот с регулярками незадалось, поэтому они автоматически ненужны и даже вредны. С ними же ещё разбираться надо. :)
Два инта из строки достать - велосипедисты тут как тут, попросишь что чуть сложней - все, не найти никого, только на форумах рассказывать.
А если попросить без QString сделать, то все - "ia po russki ne ponimat". :)


Название: Re: Парсинг строки определенного типа
Отправлено: Igors от Май 08, 2014, 10:12
С треугольниками вы тоже сели в лужу? Да, это не финдреплейсы писать на QString. :) И сортировки что-то не параллелятся. Там тоже не очень велосипедится...? Даже телефонные номера не парсятся. Зато два инта из строки достать, это вы первые. :)
К чему этот поток раздраженной иронии? :) Хотите поскандалить - без меня, умолкаю.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 10:16
Хотите поскандалить - без меня, умолкаю.
Когда по существу ответить нечего, это самых разумный шаг. :)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 08, 2014, 12:06
Ответить по существу в поток раздражённой иронии :D Мда, я так не могу, я слишком спокоен :D


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 12:27
Ответить по существу в поток раздражённой иронии :D Мда, я так не могу, я слишком спокоен :D
Вчера вы никакой раздраженной иронии не видели, что сейчас случилось?  :D


Название: Re: Парсинг строки определенного типа
Отправлено: k0p4 от Май 08, 2014, 19:30
Цитировать
Задача немного изменилась, добавились телефоны и емейлы. Что то пока не один велосипедист не рискнул это завелосипедить.
Цитировать
Цитировать
Мне алгоритм не нужен
Цитировать
добавьте к своему парсеру такую возможность

Так всё-таки не нужен или добавить?

Я же спрашивал Вас, нужно ли велосипедить? : )
Извините заранее, если опять не мне : )


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 19:41
Я же спрашивал Вас, нужно ли велосипедить? : )
Если вам времени не жалко и есть желание, то пожалуйста. :)
От наших известных велосипедистов, думаю, такое сложное решение можно не ждать...
А я покажу одну строчку с регулярным выражением для этого и скажу, что через пол года может понадобится проверять и выдергивать паспортные данные и информацию о правах.  ;)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 08, 2014, 19:49
Запомните одну вещь Old.
Краном можно построить высотный дом, при этом подвозить должен плиты камаз, а цеплять рабочие. И в конце надо будет молотком постучать по отделке.
А молотком можно построить всё в рамках разумного.

Инструмент нужно по работе выбирать, а не ставить везде краны :)


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 08, 2014, 19:57
Цитировать
Инструмент нужно по работе выбирать, а не ставить везде краны
Ох, Верес, Верес.. Расскажите нам лучше, как вы огонь добываете  ;D


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 20:01
Инструмент нужно по работе выбирать, а не ставить везде краны :)
Запомните Верес, что если вы пишите не лабораторки для школьников, то программа будет эволюционировать со временем и если вы умеете только молоток, то плиты эти вы на второй этаж уже не поднимите, даже с молотком. Поэтому, ваш начальник скорее всего вас отправит этим молотком подметать улицы и найдет парня, который умеет и кран и молоток. :)
Ну или в крайнем случае будете с вашим молотком окна вставлять, и больше вас ни к чему не подпустят.


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 08, 2014, 20:27
Со строителями поинтересуйтесь ) Если они стоят двухэтажный дом, то никто многоэтажку не будет делать :) Всё с чистого листа начнут.
Так и тут. Ставим планку что нам надо и чего ждём? Есть формат - делаем по формату, не отвлекаясь на будущее. Ведь быть может придётся всё переписывать на хаскель или, тьфу тьфу, брейнфак :D

to m_ax: огонь добываю нажатием на кнопку. Идеальный интерфейс и да, заметьте - доработки до электрической дуги не предусмотрено :D


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 20:32
Так только в лабораторках бывает: "Поставил планку и все".  ;D
Вы поспрашивайте у ребят здесь... что такое рефакторинг в большой программе, как это заменить устаревшую подсистему на новую, как легко форматы могут быть расширены или даже полностью заменены и как с этим всем новым старый код подружить... Поспрашивайте.
Куда идут велосипеды с уходом их автора из проекта, и куда потом этого автора посылает команда, которой нужно быстро этот велик переписать, потому что разобраться с ним, а тем более расширить желание ни у кого не возникает.
А пока пишешь программы один и по принципу "Написал и забыл", то оно всегда все хорошо, все планки видны и они под ногами. :)


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 08, 2014, 21:18
Цитировать
to m_ax: огонь добываю нажатием на кнопку. Идеальный интерфейс и да, заметьте - доработки до электрической дуги не предусмотрено
Да ладно.. Не скромничайте) Зачем вам кнопка?? А как же палочка, сухая кора и мышечная сила?
До этого, окажись вы в каменном веке, каждый бы догадался) там то о кнопочках народ и не подозревал даже(


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 08, 2014, 21:35
Я рад регэскпам в больших проектах :) Я счастлив их видеть при парсинге HTML ответов и запросов :D

Но я не рад тянуть 1,4 гига бустика ради 1 строчечки в лабораторке. Я не рад строке типа http://habrastorage.org/getpro/habr/comment_images/83e/075/0c6/83e0750c659f253d9c9dc8328e9291d5.png в редакторе файлов с функционалом открыть закрыть :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 21:40
Но я не рад тянуть 1,4 гига бустика ради 1 строчечки в лабораторке.
Ну вообще то бустик занимает, внимание!, 60 МЕГАбайт и большинство библиотек хедер онли, т.е. не нужно ничего тянуть.
Но ради одной строчки в лабораторке можно всегда взять ГИГАбайтный Qt. Да. :)
Вы вначале разберитесь с вопросом, а потому пишите ужастики на форумах, а то вы начинаете напоминать другого трусишку-фантазера. :)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 08, 2014, 21:49
Я имею на руках полностью собранный буст :D 1,5 Гб. Хотя я ж его компилил :D

Я разбираюсь в вопросе проектирования. И должен вам сказать, что вы впадаете в экстаз при произнесении слов "А в будущем" или "А если" или "А может быть". Нельзя написать блокнот и дать ему платформу для аналога ворда. Просто разные архитектуры и разные задачи. Интересно вы это когда - нибудь поймёте? :D



Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 08, 2014, 21:51
Но ради одной строчки в лабораторке можно всегда взять ГИГАбайтный Qt. Да. :)
Да ладно бы ещё Qt.. Так ведь даже используя только QString, их эти ГИГабайтики не смущают, не говоря уже о том, что и код с таким "народным подходом" получается совершенно не расширяемым..(

Замечу, что Верес, тем не менее, пользуется кнопкой, при добывания огня) Ну как это назвать?)


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 08, 2014, 21:53
Я разбираюсь в вопросе проектирования.
Да, мы уже в курсе  :)


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 22:00
Интересно вы это когда - нибудь поймёте? :D
Я это понял 25 лет назад. Поэтому я всегда все проектирую с прицелом на расширяемость и изменяемость. Чего и вам желаю.

Я имею на руках полностью собранный буст :D 1,5 Гб. Хотя я ж его компилил :D
У меня последняя версия.
Даем команду:
du /usr/lib/libboost_* --total -b

и получаем ответ в байтах:
57156663        итого

Сможете посчитать сколько это?
Заметим, что это вообще весь буст, поверьте у вас никогда не будет проектов, где понадобятся все его библиотеки.


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 08, 2014, 22:09
Ой, мне кажется, что сейчас самое время надевать каску, иначе велосипедисты-ретрограды будут закидывать камнями, всячески оправдывая своё невежество)


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 08, 2014, 22:21
И ещё раз повторюсь: я не против Qt, напротив, он мне очень симпатичен..  Но мы сейчас спорим о совершенно очевидных вещах, и не понятно почему (во всяком случае мне) некоторые (не буду показывать пальцем) предпочитают неоправданные велосипеды, за мешок которых рубь цена,   очевидным расширяемым и более гибким подходам, специально для этого и разработанным? Причём разработанным даже в самом Qt из коробки)    


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 22:37
Я разбираюсь в вопросе проектирования.
Даа, это выдает все ваши посты. ;)

А вот в это, я поверю скорее:
Не все работают с итераторами. Я до последнего времени больше работал с UI, чем с внутренними механизмами.
И я даже понимаю вашего начальника. ;)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 08, 2014, 23:38
to Old: "Нет, не понимаете" ©

to m_ax: Просто я работал в команде. Когда шёл проект из 4 частей, каждому досталось по части и кусочку (3 программиста). Каждая из частей работала ок. Но при этом мне и ещё 1 программисту были глубоко непонятна часть третьего. Да, там была фабрика классов, там были шаблоны, там были бустовские потоки, были умные указатели, был S11N, был OPC и ещё хзчто.  

Да, круто.
Но непонятно... Потому что чтобы исправить его код нужно месяца два изучать OPC, неделю буст, отряхнуть воспоминания о шаблонах, знать что где-то нужно держать умный указатель всё время работы, а в другом месте надо держать только при создании. И да, полное отсутствие документации. Мы могли править проекты друг друга, но его поправить не в состоянии.
Мб это характеризует нас как плохих программистов (всё возможно в этом мире © ).
Мб это характеризует 3-го как супер специалиста, выбравшего супер расширяемые гибкие инструменты.

Но мне хочется думать (и я думаю!), что код должен писаться понятным для программиста средней руки и только в случаях когда необходимо иное - превращать его в пирамиду мудрости, которую не разберёшь до конца, пока не изучишь все входящие в неё технологии и не будешь ими первоклассно владеть.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 23:42
Так расскажите, что же должен знать программист средней руки, на которого нужно ориентироваться? :)


Название: Re: Парсинг строки определенного типа
Отправлено: _OLEGator_ от Май 08, 2014, 23:45
Но мне хочется думать (и я думаю!), что код должен писаться понятным для программиста средней руки

С таким подходом выше программиста "средней руки" не вырастешь.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 08, 2014, 23:49
С таким подходом выше программиста "средней руки" не вырастешь.
Так на это и расчёт. Научился кнопки на форму класть и работай, денюшку зарабатывай.
А тут пришёл умник и давай там фабрики с шаблонами применять - непонятно. Но не учиться же...


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 08, 2014, 23:57
Поддержка проекта такого уровня потребует специалиста такого же уровня и уровнем выше. Согласны?
Вопрос - сколько программистов, умеющих применять одни и те же технологии и компоненты в одинаковой мере может встретиться в 2 фирмах?

PS я специально не привожу OPC технологию - в России она ещё пока не применяется и де факто не продаётся.

PPS я обучаюсь, но у меня, как и любого другого человека ограниченные интересы. Мне попадается задача - я решаю её, попутно узнавая различные способы решения. Я не использовал итераторы - они мне были не нужны. Я не использую regExp в простых проектах. Потому что он там не нужен. Я использую regExp в сетевых проектах. Потому что способ "в лоб" на больших и запутанных структурах сработает хуже regExp.

PPPS хых. Наткнулся на хабре на подобный холивар, который так и не окончился, холивар же.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 09, 2014, 00:06
PS я специально не привожу OPC технологию - в России она ещё пока не применяется и де факто не продаётся.
http://opcserver.ru/index.phtml
Зайдите к ним в новости и посмотрите год начала разработок.:)


Название: Re: Парсинг строки определенного типа
Отправлено: m_ax от Май 09, 2014, 00:14
to m_ax: Просто я работал в команде.
И это замечательно) И что из того? Ну вот я сейчас тоже работаю над кое чем не один.. Вот представляете, так и не смог приучить пользоваться Gitом..((
 
Цитировать
Потому что чтобы исправить его код нужно месяца два изучать OPC, неделю буст, отряхнуть воспоминания о шаблонах, знать что где-то нужно держать умный указатель всё время работы, а в другом месте надо держать только при создании.

Да, там была фабрика классов, там были шаблоны, там были бустовские потоки, были умные указатели, был S11N, был OPC и ещё хзчто.  
Ну дык чья это вина, что вы не смогли с этим разобраться? Уж если вы пишите на плюсах, то умение разбираться с бустом.. мм.. ладно..

Цитировать
Мы могли править проекты друг друга, но его поправить не в состоянии.
Так это всё же его вина, да?)

Цитировать
Мб это характеризует нас как плохих программистов
... (не знаю...)


Цитировать
Но мне хочется думать (и я думаю!), что код должен писаться понятным для программиста средней руки...
Вот эта часть предложения уже очень спорна..((  
Как уже писали выше, с таким расчётом, вы программитом средней руки так и останетесь.(




Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 09, 2014, 00:24
to Old: Использовался OPC UA, собственно она разительно отличается от предыдущих ^.^

to m_ax: никто не мешает писать код, понятный программистам средней руки и быть на уровень выше :) Программирование это 90% архитектура, планирование и 10% код.


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 09, 2014, 00:46
to m_ax: никто не мешает писать код, понятный программистам средней руки и быть на уровень выше :) Программирование это 90% архитектура, планирование и 10% код.
К сожалению это не возможно. :(
Или куча if/else/switch/case или фабрики и возможность расширяться даже без перекомпиляции.


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 09, 2014, 00:50
http://s5.pikabu.ru/post_img/2014/05/08/11/1399573364_208371607.jpg :D

Холивар однако без конца) Я самоустраняюсь :D


Название: Re: Парсинг строки определенного типа
Отправлено: Old от Май 09, 2014, 05:47
Холивар однако без конца) Я самоустраняюсь :D
Но куда же вы? :(
Печально. Так мы и не узнаем что же знает программист средней руки, как далеко он ушёл от вахтерши бабы Маши? На чей уровень нам теперь ориентироваться?
А то напишешь в своей программе шаблон, а этот программист не поймет, расстроиться. Как с этим жить? :)


Название: Re: Парсинг строки определенного типа
Отправлено: Bepec от Май 20, 2014, 10:24
(http://img0.joyreactor.cc/pics/post/xkcd-%D0%9A%D0%BE%D0%BC%D0%B8%D0%BA%D1%81%D1%8B-xkcdru-%D0%BF%D0%B5%D1%80%D0%B5%D0%B2%D0%B5%D0%BB-%D1%81%D0%B0%D0%BC-1256480.png)