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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Замена подстрок и escape syntax  (Прочитано 9714 раз)
sergs
Гость
« : Январь 07, 2017, 08:38 »

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

Количество подстрок, которые необходимо заменить заранее не известно, но известен список возможных подстрок (т.к. $user, $version и т.д.). Как можно реализовать подобное?
Записан
Bepec
Гость
« Ответ #1 : Январь 07, 2017, 15:40 »

Самое простое это
Код:
replace( "$$", "@MyCodeEscapeSymbol@");
replace в цикле
replace("@MyCodeEscapeSymbol@", "$$");
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #2 : Январь 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
 
Записан

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

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Январь 07, 2017, 16:57 »

Не знаю как сейчас там в Qt, но как вариант это просто реализуется на xpressive
m_ax, вы сейчас вероломно зашли на чужую территорию и истоптали все цветы. Берегитесь... Подмигивающий  Смеющийся
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4724



Просмотр профиля WWW
« Ответ #4 : Январь 07, 2017, 17:02 »

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

Изучением 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

Сообщений: 2094



Просмотр профиля
« Ответ #5 : Январь 07, 2017, 17:06 »

Цитировать
m_ax, вы сейчас вероломно зашли на чужую территорию и истоптали все цветы. Берегитесь...  Подмигивающий Смеющийся
Смеющийся Представил сейчас себе эту картину) Как я цветы им топчу Смеющийся 
Смотрите, они ещё и вас заодно того..) 
Записан

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

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #6 : Январь 07, 2017, 17:24 »

можно делать replace через регулярку QString("(?<!\\$)\\%1").arg("$user" /* сюда вставить элемент массива */)

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

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

Arch Linux Plasma 5
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4724



Просмотр профиля WWW
« Ответ #7 : Январь 07, 2017, 18:30 »

да, правда. ну тут можно и без буста распарсить строку в один проход без особых проблем Улыбающийся
Записан

Изучением 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

Сообщений: 2094



Просмотр профиля
« Ответ #8 : Январь 07, 2017, 18:48 »

да, правда. ну тут можно и без буста распарсить строку в один проход без особых проблем Улыбающийся
Да, конечно можно) Тут даже тему уже была аналогичная http://www.prog.org.ru/index.php?topic=30197.msg222882#msg222882
Записан

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

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #9 : Январь 07, 2017, 22:21 »

Создал тему в кладовке с готовым решением этой проблемы в рамках Qt инструментария http://www.prog.org.ru/topic_30886_0.html
Записан

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

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Январь 08, 2017, 08:14 »

Это самое плохое..
И после этого мы удивляемся,
Ага, а вот это, значит, хорошее
Код
C++ (Qt)
sregex re = (s1= +as_xpr('$') >> +_w);
 

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

Да и велик можно интересно обобщить, развить - и даже без перекрытия оператора ()  Улыбающийся  
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #11 : Январь 08, 2017, 16:16 »

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

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

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

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Январь 09, 2017, 08:37 »

Да, один раз стоит сделать над собой усилие и разобраться в этом, ничего страшного в этом нет) Даже полезно:
В свое время китайские товарищи формулировали это примерно так
Цитировать
Двадцать лет упорного труда - тысяча лет счастья
Записан
sergs
Гость
« Ответ #13 : Январь 09, 2017, 11:03 »

m_ax, вариант с boost не подходит. Это новая (и объемная) зависимость в проекте. Но за подсказку спасибо, и за     
qRegexReplace тоже. Буду изучать и дорабатывать для поддержки escape syntax.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2094



Просмотр профиля
« Ответ #14 : Январь 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;
}
 
Записан

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

Arch Linux Plasma 5
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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