Russian Qt Forum

Qt => Общие вопросы => Тема начата: sergs от Январь 07, 2017, 08:38



Название: Замена подстрок и escape syntax
Отправлено: sergs от Январь 07, 2017, 08:38
Необходимо выполнить замену подстрок в строке, но не просто замену, а учитывать экранирование. Например, есть строка
Код:
http://server.com/$user/docs/$version
необходимо заменить $user и $version на некие значения. В данном примере экранирования нет и все решается вызовом метода replace() в цикле. Другой пример
Код:
D:\share\$user\$$version
тут используется экранирование и заменить необходимо только $user, а $$version остается.

Количество подстрок, которые необходимо заменить заранее не известно, но известен список возможных подстрок (т.к. $user, $version и т.д.). Как можно реализовать подобное?


Название: Re: Замена подстрок и escape syntax
Отправлено: Bepec от Январь 07, 2017, 15:40
Самое простое это
Код:
replace( "$$", "@MyCodeEscapeSymbol@");
replace в цикле
replace("@MyCodeEscapeSymbol@", "$$");


Название: Re: Замена подстрок и escape syntax
Отправлено: m_ax от Январь 07, 2017, 16:50
Цитировать
Самое простое это
Это самое плохое..
И после этого мы удивляемся, что всё больше и больше, казалось бы нехитрых приложений, отжирают столько памяти, что не напасешься.. 

Не знаю как сейчас там в Qt, но как вариант это просто реализуется на xpressive

Код
C++ (Qt)
#include <iostream>
#include <string>
#include <map>
#include <boost/xpressive/xpressive.hpp>
 
using namespace std;
using namespace boost::xpressive;
 
 
class substitute
{
public:
   substitute()
   {
       m_map["$user"] = "terminator";
       m_map["$version"] = "T1000";
   }
 
   string operator()(const smatch & match) const
   {
       auto it = m_map.find(match[1]);
       if (it != m_map.end())
           return it->second;
 
       return match[1];
   }
 
private:
   map<string, string> m_map;
};
 
 
int main()
{
 
   std::string in("http://server.com/$user/docs/$version D:\\share\\$user\\$$version");
 
   sregex re = (s1= +as_xpr('$') >> +_w);
 
   std::string out = regex_replace(in, re, substitute());
 
   std::cout << out << std::endl;
 
   return 0;
}
 


output:
Код
Bash
http://server.com/terminator/docs/T1000 D:\share\terminator\$$version
 


Название: Re: Замена подстрок и escape syntax
Отправлено: Old от Январь 07, 2017, 16:57
Не знаю как сейчас там в Qt, но как вариант это просто реализуется на xpressive
m_ax, вы сейчас вероломно зашли на чужую территорию и истоптали все цветы. Берегитесь... ;)  ;D


Название: Re: Замена подстрок и escape syntax
Отправлено: kambala от Январь 07, 2017, 17:02
можно делать replace через регулярку QString("(?<!\\$)\\%1").arg("$user" /* сюда вставить элемент массива */)


Название: Re: Замена подстрок и escape syntax
Отправлено: m_ax от Январь 07, 2017, 17:06
Цитировать
m_ax, вы сейчас вероломно зашли на чужую территорию и истоптали все цветы. Берегитесь...  ;) ;D
;D Представил сейчас себе эту картину) Как я цветы им топчу ;D 
Смотрите, они ещё и вас заодно того..) 


Название: Re: Замена подстрок и escape syntax
Отправлено: m_ax от Январь 07, 2017, 17:24
можно делать replace через регулярку QString("(?<!\\$)\\%1").arg("$user" /* сюда вставить элемент массива */)

Слабое место подхода с Qt-шным реплэйсом для данной задачи то, что придётся все N раз (для каждой подстроки) проходится по тексту..
Если мы имеем большой текст и список подстрок, то это, возможно, будет узким местом..   


Название: Re: Замена подстрок и escape syntax
Отправлено: kambala от Январь 07, 2017, 18:30
да, правда. ну тут можно и без буста распарсить строку в один проход без особых проблем :)


Название: Re: Замена подстрок и escape syntax
Отправлено: m_ax от Январь 07, 2017, 18:48
да, правда. ну тут можно и без буста распарсить строку в один проход без особых проблем :)
Да, конечно можно) Тут даже тему уже была аналогичная http://www.prog.org.ru/index.php?topic=30197.msg222882#msg222882 (http://www.prog.org.ru/index.php?topic=30197.msg222882#msg222882)


Название: Re: Замена подстрок и escape syntax
Отправлено: m_ax от Январь 07, 2017, 22:21
Создал тему в кладовке с готовым решением этой проблемы в рамках Qt инструментария http://www.prog.org.ru/topic_30886_0.html (http://www.prog.org.ru/topic_30886_0.html)


Название: Re: Замена подстрок и escape syntax
Отправлено: Igors от Январь 08, 2017, 08:14
Это самое плохое..
И после этого мы удивляемся,
Ага, а вот это, значит, хорошее
Код
C++ (Qt)
sregex re = (s1= +as_xpr('$') >> +_w);
 

А что такое as_xpr, _w и др? Откуда человек об этом может знать? Да ниоткуда, это надо просто "выучить", тупо запомнить, продолбив N дустовских примеров. Мне кажется это не очень творческий процесс :) Я понимаю что он имеет смысл если такие задачки идут бурным потоком. Но у меня-то такого нет, что-то подобное возникает раз в полгода. Даже если я когда-то "учил" - точно придется вспоминать, а за это время я великом сделаю раз 10. Ну и смысл?

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


Название: Re: Замена подстрок и escape syntax
Отправлено: m_ax от Январь 08, 2017, 16:16
Цитировать
Откуда человек об этом может знать? Да ниоткуда, это надо просто "выучить", тупо запомнить, продолбив N дустовских примеров.
Да, один раз стоит сделать над собой усилие и разобраться в этом, ничего страшного в этом нет) Даже полезно: как говорил барон Карл Фридрих Иероним фон Мюнхгаузен- мыслящий человек просто обязан время от времени вытягивать себя за волосы из болота) Вместе с конём)

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


Название: Re: Замена подстрок и escape syntax
Отправлено: Igors от Январь 09, 2017, 08:37
Да, один раз стоит сделать над собой усилие и разобраться в этом, ничего страшного в этом нет) Даже полезно:
В свое время китайские товарищи формулировали это примерно так
Цитировать
Двадцать лет упорного труда - тысяча лет счастья


Название: Re: Замена подстрок и escape syntax
Отправлено: sergs от Январь 09, 2017, 11:03
m_ax, вариант с boost не подходит. Это новая (и объемная) зависимость в проекте. Но за подсказку спасибо, и за     
qRegexReplace тоже. Буду изучать и дорабатывать для поддержки escape syntax.


Название: Re: Замена подстрок и escape syntax
Отправлено: m_ax от Январь 09, 2017, 12:39
Цитировать
Буду изучать и дорабатывать для поддержки escape syntax.
А что там дорабатывать? Просто регулярку нужно правильно написать (kambala уже вам её написал):

Код
C++ (Qt)
#include <QCoreApplication>
#include <QDebug>
#include <QMap>
 
#include "qregexreplace.h"
 
class Substitute
{
public:
   Substitute()
   {
       m_map["$user"] = "terminator";
       m_map["$version"] = "T1000";
   }
 
   QString operator()(const QString & match) const
   {
       auto it = m_map.find(match);
       if (it != m_map.end())
           return it.value();
 
       return match;
   }
 
private:
   QMap<QString, QString> m_map;
};
 
 
int main()
{
   QString str = "http://server.com/$user/docs/$version D:\\share\\$user\\$$version";
 
   QRegularExpression rx("(?<!\\$)(\\$\\w+)");
 
   qDebug() << qRegexReplace(str, rx, Substitute());
 
   return 0;
}