Russian Qt Forum
Ноябрь 23, 2024, 07:17 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 ... 13 14 [15] 16 17 18   Вниз
  Печать  
Автор Тема: Регулярное выражение с QString  (Прочитано 160838 раз)
Spark
Гость
« Ответ #210 : Август 04, 2013, 16:32 »

Все до кучи накропал. Работает. Завтра буду разбирать ошибки.
Код
C++ (Qt)
void MainWindow::textoryFromBuffer()
{
   QClipboard *clipboard = QApplication::clipboard();
   QString originalBuffer = clipboard->text();
   QTextStream bufferStream( & originalBuffer );
   QString itemBufStr, itemTextStr;
   QStringList textList;
 
   textory.clear();
 
   do
   {
       itemBufStr = bufferStream.readLine();
 
       itemTextStr = itemBufStr.trimmed();
       if ( itemTextStr.isEmpty() )
           continue;
 
       textList.prepend( itemTextStr );
   } while ( !bufferStream.atEnd() );
 
   textory.enableAdd( true );
 
   foreach (QString itm, textList)
       textory.addItem( Textory::Item( 1, itm ) );
 
   cfg.textoryName = "From Buffer";
   ui.textoryPaneWidget->getTextoryLabel().setText( cfg.textoryName );
}
« Последнее редактирование: Август 04, 2013, 17:04 от Spark » Записан
Spark
Гость
« Ответ #211 : Август 04, 2013, 16:41 »

...посте, в прикрепленном архиве я набрасывал примерчик - там все это работает с таблицей. Можете не долго думая взять за основу и не мучаться с табуляциями. За одно мимоходом ознакомитесь с концепцией модель-представление - пригодиться в будущем.
Спасибо. Попробую разобрать пример и использовать. Хотел я отложить в ящик, вроде и так все не плохо работает, но видимо придется заняться оформлением вывода. Тем более предполагается более крутая обработка текста.
« Последнее редактирование: Август 04, 2013, 17:09 от Spark » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #212 : Август 05, 2013, 06:10 »

Код
C++ (Qt)
enum {
sort_None = 0,
sort_Freq = 1,
sort_Crazy = 2,   // даете имена по смыслу, этл для примера
};
Компактнее не становится. Только для того, кто после меня будет ковырять код? Просто ноль вставил.
Выполняйте, и для typeOffset тоже. Свое мнение будете высказывать когда освоите что говорят  Улыбающийся
« Последнее редактирование: Август 05, 2013, 11:52 от Igors » Записан
Spark
Гость
« Ответ #213 : Август 05, 2013, 11:17 »

Выполняйте, и для typeOffset тоже. Свое мнение будете высказывать когда освоите что говорят  Улыбающийся
Выполнить не проблема. Но было бы интересно знать преимущества. Пока только код стал длиннее. Разве, что читабельней? Опять правила хорошего кода?
Ok! Заодно добавил немного статистики - ПРОЦЕНТ ОСТАВЛЕННЫХ СЛОВ ОТ КОЛИЧЕСТВА ОРИГИНАЛЬНЫХ:
Код
C++ (Qt)
void MainWindow::wordStat()
{
   QTime tm;
   tm.start();
 
   const Config::Preferences & pref = cfg.preferences;
   QClipboard *clipboard = QApplication::clipboard();
   QString originalText = clipboard->text();
   QString addZero;
   QStringList listFull;
   QStringList frequencyList;
 
   qDebug() << "Reade Data: " << tm.elapsed();
   tm.start();
 
   textory.clear();
   textory.enableAdd( true );
 
   // ОСТАВЛЯЕМ: ВЕСЬ ТЕКСТ/АНГЛИЙСКИЙ/РУССКИЙ
   const QString mask[3] = {
       QString("[\\s\\W\\d_]+"),
       QString("[^a-z]+"),
       QString::fromUtf8("[^а-яё]+"),
   };
   QRegExp rexp(mask[pref.langStatSort]);
   listFull = originalText.toLower().split(rexp, QString::SkipEmptyParts);
 
   qDebug() << "Data split: " << tm.elapsed();
   tm.start();
 
   // ПОСТРОЕНИЕ СПИСКА
   QRegExp rx(muRegExp);
   rx.setPatternSyntax(QRegExp::Wildcard);
   enum {
       sort_Amount = 0,
       sort_Alphabet = 1,
       sort_None = 2
   };
 
   QHash<QString, int> freqHash;
   foreach (QString s, listFull) ++freqHash[s];
 
   frequencyList.reserve(listFull.size());
   foreach (QString s, listFull) {
       if (s.size() < pref.minSizeWord || s.size() > pref.maxSizeWord )continue;
       if (!muRegExp.isEmpty() && !rx.exactMatch(s))continue;
       int & num = freqHash[s];
       if (num < 0) continue;
       if (num >= pref.minRepeats ) {
           if  (pref.typeOfSort != sort_Amount)
               frequencyList.prepend(s + '\t' + QString::number(long(num)));
           else {
               addZero = QString::number(long(num)).rightJustified(6, '0');
               frequencyList.prepend(addZero + s + '\t' + QString::number(long(num)));
           }
       }
       num = -num;
   }
 
   qDebug() << "Count: " << tm.elapsed();
   tm.start();
 
   if (pref.typeOfSort != sort_None)qSort(frequencyList);
 
   // ВЫВОД СПИСКА
   qDebug() << "Data sort: " << tm.elapsed();
   tm.start();
 
   if (pref.typeOfSort == sort_Amount || pref.typeOfSort == sort_None) {
       foreach (QString itm, frequencyList) {
           if(pref.typeOfSort == 0)itm.remove(0,6);
           textory.addItem( Textory::Item( 1, itm ) );
       }
   }
 
   if (pref.typeOfSort == sort_Alphabet) {
       QListIterator<QString>itm(frequencyList);
       itm.toBack();
       while (itm.hasPrevious())
           textory.addItem( Textory::Item( 1, itm.previous() ) );
   }
 
   qDebug() << "Out list: " << tm.elapsed();
   tm.start();
 
   // ПРОЦЕНТ ОСТАВЛЕННЫХ СЛОВ ОТ КОЛИЧЕСТВА ОРИГИНАЛЬНЫХ
   double full(freqHash.size());
   double real(textory.size());
 
   QString freqStat = "/" + QString::number(long(freqHash.size())) + "/" + QString::number(double(real * 100 / full), 'f', 2).remove(QRegExp("\\.00")) + "%";
 
   cfg.textoryName = "Frequency list (" + QString::number(long(listFull.size())) + freqStat + ")";
   ui.textoryPaneWidget->getTextoryLabel().setText( cfg.textoryName );
 
   qDebug() << "Write name: " << tm.elapsed();
}
« Последнее редактирование: Август 05, 2013, 11:26 от Spark » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #214 : Август 05, 2013, 12:30 »

Код
C++ (Qt)
   enum {
       sort_Amount = 0,
       sort_Alphabet = 1,
       sort_None = 2
   };
 
Это выносится в начало cpp файла, или h файла если это класс. None обычно соответствует нулю. Имена подбираются более тщательно, напр sort_Amount - слишком общее, лучше напр sort_ByCount

Вместо этого
Код
C++ (Qt)
   if (pref.typeOfSort == sort_Amount || pref.typeOfSort == sort_None) {
       foreach (QString itm, frequencyList) {
           if(pref.typeOfSort == 0)itm.remove(0,6);
           textory.addItem( Textory::Item( 1, itm ) );
       }
   }
 
   if (pref.typeOfSort == sort_Alphabet) {
       QListIterator<QString>itm(frequencyList);
       itm.toBack();
       while (itm.hasPrevious())
           textory.addItem( Textory::Item( 1, itm.previous() ) );
   }
 

Лучше так
Код
C++ (Qt)
QStringList & lst = frequencyList;
const int ilimit = lst.size();
for (int i = 0; i < limit; ++i) {
   switch (pref.typeOfSort) {
     case sort_None:
       textory.addItem(Textory::Item(1, lst[i]);
       break;
 
     case sort_Amount:
       textory.addItem(Textory::Item(1, lst[i].remove(0, 6)));
       breakl;  
 
     case sort_Alphabet:
       textory.addItem(Textory::Item(1, lst[limit - 1 - i]);
       break;
  }
}
 
Цель - не написать "как можно короче" (это обычно само получается), а разложить все на свои места. А то появится еще режим - и опять месить if'ы. В общем, к культуре надо приучаться  Улыбающийся
Записан
Spark
Гость
« Ответ #215 : Август 05, 2013, 16:57 »

Хорошо, лишь бы не было медленней. Как раз наклевывается новый режим.
Поправил:
Код
C++ (Qt)
void MainWindow::wordStat()
{
   QTime tm;
   tm.start();
 
   const Config::Preferences & pref = cfg.preferences;
   QClipboard *clipboard = QApplication::clipboard();
   QString originalText = clipboard->text();
   QString addZero;
   QStringList listFull;
   QStringList frequencyList;
 
   qDebug() << "Reade Data: " << tm.elapsed();
   tm.start();
 
   textory.clear();
   textory.enableAdd( true );
 
   // ОСТАВЛЯЕМ: ВЕСЬ ТЕКСТ/АНГЛИЙСКИЙ/РУССКИЙ
   const QString mask[3] = {
       QString("[\\s\\W\\d_]+"),
       QString("[^a-z]+"),
       QString::fromUtf8("[^а-яё]+"),
   };
   QRegExp rexp(mask[pref.langStatSort]);
   listFull = originalText.toLower().split(rexp, QString::SkipEmptyParts);
 
   qDebug() << "Data split: " << tm.elapsed();
   tm.start();
 
   // ПОСТРОЕНИЕ СПИСКА
   QRegExp rx(muRegExp);
   rx.setPatternSyntax(QRegExp::Wildcard);
   enum {
       sort_Amount = 0,
       sort_Alphabet = 1,
       sort_None = 2
   };
 
   QHash<QString, int> freqHash;
   foreach (QString s, listFull) ++freqHash[s];
 
   frequencyList.reserve(listFull.size());
   foreach (QString s, listFull) {
       if (s.size() < pref.minSizeWord || s.size() > pref.maxSizeWord )continue;
       if (!muRegExp.isEmpty() && !rx.exactMatch(s))continue;
       int & num = freqHash[s];
       if (num < 0) continue;
       if (num >= pref.minRepeats && num <= pref.maxRepeats) {
           if  (pref.typeOfSort != sort_Amount)
               frequencyList.prepend(s + '\t' + QString::number(long(num)));
           else {
               addZero = QString::number(long(num)).rightJustified(6, '0');
               frequencyList.prepend(addZero + s + '\t' + QString::number(long(num)));
           }
       }
       num = -num;
   }
 
   qDebug() << "Count: " << tm.elapsed();
   tm.start();
 
   if (pref.typeOfSort != sort_None)qSort(frequencyList);
 
   // ВЫВОД СПИСКА
   qDebug() << "Data sort: " << tm.elapsed();
   tm.start();
 
 
   QStringList & lst = frequencyList;
   const int ilimit = lst.size();
   for (int i = 0; i < ilimit; ++i) {
       switch (pref.typeOfSort) {
         case sort_None:
           textory.addItem(Textory::Item(1, lst[i]));
           break;
 
         case sort_Amount:
           textory.addItem(Textory::Item(1, lst[i].remove(0, 6)));
           break;
 
         case sort_Alphabet:
           textory.addItem(Textory::Item(1, lst[ilimit - 1 - i]));
           break;
      }
   }
 
   qDebug() << "Out list: " << tm.elapsed();
   tm.start();
 
   // ПРОЦЕНТ ОСТАВЛЕННЫХ СЛОВ ОТ КОЛИЧЕСТВА ОРИГИНАЛЬНЫХ
   double full(freqHash.size());
   double real(textory.size());
 
   QString freqStat = "/" + QString::number(long(freqHash.size())) + "/" + QString::number(double(real * 100 / full), 'f', 2).remove(QRegExp("\\.00")) + "%";
 
   cfg.textoryName += " (" + QString::number(long(listFull.size())) + freqStat + ")";
   ui.textoryPaneWidget->getTextoryLabel().setText( cfg.textoryName );
 
   qDebug() << "Write name: " << tm.elapsed();
}
По сути я пользуюсь стандартной булевой алгеброй. Остальные приемы только только постигаю. Так приучите меня к вещам, которые я никогда не применял Улыбающийся.
Спасибо!
Записан
Spark
Гость
« Ответ #216 : Август 05, 2013, 17:07 »

Однако кое, что добавил:
Записан
Spark
Гость
« Ответ #217 : Август 05, 2013, 20:26 »

Подобного рода текст:
Цитировать
Слово1
  слово
  слово

слово2
слово3
  слово

слово4
  ...
Надо собрать слова без пробела или табуляции в начале новой строки. Как организовать сплит? Пытаюсь через регесп, что бы использовать в коде:
Код
C++ (Qt)
   // ОСТАВЛЯЕМ: ВЕСЬ ТЕКСТ/АНГЛИЙСКИЙ/РУССКИЙ
   const QString mask[3] = {
       QString("[\\s\\W\\d_]+"),
       QString("[^a-z]+"),
       QString::fromUtf8("[^а-яё]+"),
   };
Не получается.
Конечно можно предварительно через те же регеспы удалить ненужные строки. Но хотелось бы сделать более оптимально, без промежуточных операций.
« Последнее редактирование: Август 06, 2013, 09:28 от Spark » Записан
Spark
Гость
« Ответ #218 : Август 06, 2013, 04:03 »

Так пока сделал:
Код
C++ (Qt)
   const QString mask[4] = {
...
       QString("\n[\\t].*\n[^\\t]"),
   };
   QRegExp rexp(mask[pref.langStatSort]);
   rexp.setMinimal(true);
   listFull = originalText.toLower().split(rexp, QString::SkipEmptyParts);
Работает, но вроде не все верно. Вроде как не учтен конец страницы. Если его захватить, то к пунктам списка добавляется пустая строка сверху и снизу:
Цитировать
Слово1


слово2


слово3
   
Ладно, прибежим с работы, разберемся.
« Последнее редактирование: Август 06, 2013, 04:26 от Spark » Записан
Spark
Гость
« Ответ #219 : Август 07, 2013, 14:54 »

Намаялся со сплиттером (для спец текста) с помощью регурярок. Не получилось. А жаль. Сделал предварительную зачистку. Тут то-же не так гладко как хотелось бы. Затруднение не в том, что бы очистить, а в том, что бы после этого подсчитать статистические результаты. Пришлось несколько разделить процесс.
В общем так пока. Работает не хуже чем остальные режимы, даже быстрее, но как то не очень красиво. Покритикуйте:
Код
C++ (Qt)
void MainWindow::wordStat()
{
   QTime tm;
   tm.start();
 
   const Config::Preferences & pref = cfg.preferences;
   QClipboard *clipboard = QApplication::clipboard();
   QString originalText = clipboard->text();
   QString addZero;
   QStringList listFull;
   QStringList frequencyList;
   int xlsCountFull(0);
 
   qDebug() << "Reade Data: " << tm.elapsed();
   tm.start();
 
   textory.clear();
   textory.enableAdd( true );
 
   // ОСТАВЛЯЕМ: ВЕСЬ ТЕКСТ/АНГЛИЙСКИЙ/РУССКИЙ
   const QString mask[4] = {
       QString("[\\s\\W\\d_]+"),
       QString("[^a-z]+"),
       QString::fromUtf8("[^а-яё]+"),
       QString("\n"),
   };
   QRegExp rexp(mask[pref.langStatSort]);
   rexp.setMinimal(true);
   listFull = originalText.toLower().split(rexp, QString::SkipEmptyParts);
 
   qDebug() << "Data split: " << tm.elapsed();
   tm.start();
 
   // ПОСТРОЕНИЕ СПИСКА
   QRegExp rx(muRegExp);
   rx.setPatternSyntax(QRegExp::Wildcard);
   enum {
       sort_Amount = 0,
       sort_Alphabet = 1,
       sort_None = 2
   };
 
   QHash<QString, int> freqHash;
   foreach (QString s, listFull) {
       if (pref.langStatSort == 3 && (s.startsWith("\t") || s.startsWith(" ") || s.startsWith("#") || s.startsWith("{{")))continue;
       ++freqHash[s];
   }
 
   frequencyList.reserve(listFull.size());
   foreach (QString s, listFull) {
 
       if (pref.langStatSort == 3 && (s.startsWith("\t") || s.startsWith(" ") || s.startsWith("#") || s.startsWith("{{")))continue;
 
       ++xlsCountFull;
 
       if (s.size() < pref.minSizeWord || s.size() > pref.maxSizeWord )continue;
       if (!muRegExp.isEmpty() && !rx.exactMatch(s))continue;
       int & num = freqHash[s];
//        if (num < 0) continue;
 
       if (num >= pref.minRepeats && num <= pref.maxRepeats) {
           if  (pref.typeOfSort != sort_Amount)
               frequencyList.prepend(s + '\t' + QString::number(long(num)));
           else {
               addZero = QString::number(long(num)).rightJustified(6, '0');
               frequencyList.prepend(addZero + s + '\t' + QString::number(long(num)));
           }
       }
//        num = -num;
   }
 
   qDebug() << "Count: " << tm.elapsed();
   tm.start();
 
   if (pref.typeOfSort != sort_None)qSort(frequencyList);
 
   // ВЫВОД СПИСКА
   qDebug() << "Data sort: " << tm.elapsed();
   tm.start();
 
   QStringList & lst = frequencyList;
   const int ilimit = lst.size();
   for (int i = 0; i < ilimit; ++i) {
       switch (pref.typeOfSort) {
       case sort_None:
           textory.addItem(Textory::Item(1, lst[i]));
           break;
 
       case sort_Amount:
           textory.addItem(Textory::Item(1, lst[i].remove(0, 6)));
           break;
 
       case sort_Alphabet:
           textory.addItem(Textory::Item(1, lst[ilimit - 1 - i]));
           break;
       }
   }
 
   qDebug() << "Out list: " << tm.elapsed();
   tm.start();
 
   // ПРОЦЕНТ ОСТАВЛЕННЫХ СЛОВ ОТ КОЛИЧЕСТВА ОРИГИНАЛЬНЫХ
   double realSort(textory.size());
   double sortWithDoubles (xlsCountFull);
   double sortNoDoubles (freqHash.size());
 
   QString freqStat = "/" + QString::number(long(sortNoDoubles)) + "/" + QString::number(double(realSort * 100 / sortNoDoubles), 'f', 2).remove(QRegExp("\\.00")) + "%";
 
   cfg.textoryName += " (" + QString::number(long(sortWithDoubles)) + freqStat + ")";
   ui.textoryPaneWidget->getTextoryLabel().setText( cfg.textoryName );
 
   qDebug() << "Write name: " << tm.elapsed();
}

Не совсем ясно для чего это (может отпала необходимость):
        if (num < 0) continue;
        ...
        num = -num;
Пока закомментировал.
« Последнее редактирование: Август 07, 2013, 14:56 от Spark » Записан
Spark
Гость
« Ответ #220 : Август 07, 2013, 15:09 »

Ясно. Раскомментировал Улыбающийся.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #221 : Август 07, 2013, 16:18 »

Покритикуйте:
Код
C++ (Qt)
   rx.setPatternSyntax(QRegExp::Wildcard);
   enum {
       sort_Amount = 0,
       sort_Alphabet = 1,
       sort_None = 2
   };
 
   QHash<QString, int> freqHash;
   foreach (QString s, listFull) {
       if (pref.langStatSort == 3 && (s.startsWith("\t") || s.startsWith(" ") || s.startsWith("#") || s.startsWith("
Позиция один: научитесь использовать константы и enum'ы. Вбивать числа/строки прямо в код метода = западло. Чего Вы лепите тройку если завели enum? Был разговор выносить enum в начало файла, имена подобрать со вкусом. Вот сделаете с любовью (а не так чтоб отвязаться) - тогда поговорим дальше. А пока свободен  Улыбающийся
Записан
Spark
Гость
« Ответ #222 : Август 09, 2013, 17:17 »

Пытаюсь вместо буфера подставить текстовый файл:
Код
C++ (Qt)
   QFile file( texFilename );
   if ( file.open( QFile::ReadOnly | QIODevice::Text ) )
   {
       QByteArray text = file.readAll();
       Qstring originalText = text;
...
Если текст в utf8 то все  в порядке. В utf16 не читает. Соответственно ясно, что надо как то установить кодек.
Пока пытаюсь разобраться самостоятельно, может кто подскажет как поступить?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #223 : Август 09, 2013, 21:22 »

QString::fromUtf16()
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #224 : Август 09, 2013, 23:42 »

QString::fromUtf16()

Эх, kambala, здесь ИМХО, проблема гораздо глубже.. Все эти fromUtf16/8 и т.д. всего лишь частности.. в которых Spark копается уже больше месяца(..

Здесь изначально проблема в самой архитектуре.. Вот представьте, ему понадобится выводить статистику не слов, а, скажем фраз. И что? Всё, что он тут написал развалится тут же... А если в будущем возникнет необходимость для пользователя "на лету" конструировать правила для выцепления каких то лексем и т.д.. Зациклившись на сплите такие задачи кажутся безнадёжными.. Но это всего лишь следствие( Причина в том, что Sark пренебрегая реально дельными советами, закапывается в совершенно не существенные на данном этапе детали..

2Spark Вот дельный совет, который для вас был уже озвучен не однократно: Перед тем как браться за реальный проект, нужно сесть, успокоиться, возможно, посмотреть в окно, взять листок бумаги и ручку и набросать примерный план того, что и как должно справляться с поставленной задачей: какие основные сущности следует ввести, что должна делать конкретная сущность и какие взаимосвязи между ними должны быть.. Этот процесс не быстрый, возможно он займёт не один день.. и всё же.. После этого более детально определяется интерфейс каждой сущьности с расчётом возможных потенциальных расширений в будущем. Здесь, пожалуй, самый ответственный момент, которому нужно уделить большее внимание. И это один из самых ответственных моментов в разработке архитектуры, который может занять большую часть времени.

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

          
« Последнее редактирование: Август 09, 2013, 23:45 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: 1 ... 13 14 [15] 16 17 18   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.387 секунд. Запросов: 23.