Как быть с %1 в аргументе QString::arg()?

Все любят

QString("Put something here %1 and here %2")
    .arg(replacement1)
    .arg(replacement2);

но все начинает чесаться, как только у вас появляется малейший шанс, что replacement1 на самом деле содержит %1 или даже %2 где-нибудь. Затем второй QString::arg() заменит только повторно введенный %1 или оба %2 вхождения. В любом случае, вы не получите буквальное "%1", которое вы, вероятно, намеревались.

Есть ли какой-то стандартный трюк, чтобы преодолеть это?

Если вам нужен пример для игры, возьмите этот

#include <QCoreApplication>
#include <QDebug>

int main()
{
    qDebug() << QString("%1-%2").arg("%1").arg("foo");
    return 0;
}

Это выведет

"foo-%2"

вместо

"%1-foo"

как и следовало ожидать (нет).

    qDebug() << QString("%1-%2").arg("%2").arg("foo");

дает

"foo-foo"

и

    qDebug() << QString("%1-%2").arg("%3").arg("foo");

дает

"%3-foo"

person Tilman Vogel    schedule 09.03.2011    source источник
comment
Я знаю, я мог бы просто использовать конкатенацию строк, используя operator + (), но в некоторых местах, например. перевод с использованием tr(), хотелось бы сохранить возможность переупорядочивать аргументы в шаблоне.   -  person Tilman Vogel    schedule 09.03.2011
comment
Ух ты! Я никогда не сталкивался с таким случаем, но если перевод представляет собой строку %1 (в отличие от 1%, например), то он вообще не будет работать правильно. Это действительно не имеет смысла. Похоже, они повторно применяют аргументы к результату снова и снова.   -  person Alexis Wilke    schedule 14.11.2015
comment
Разве не было возможности псевдоэкранировать %1, написав %%1? Тем не менее, функциональность использования процентного маркера в arg-вызове хороша. Представьте, что у вас есть стандартная строка ошибки, использующая %1 для замены where и %2 для замены what — теперь в некоторых случаях вы просто заменяете where строкой, а в других вам нужно число. В случае строки вы, возможно, захотите поместить вокруг нее апострофы, в случае числа хэштег перед ним будет полезен для улучшения читаемости. Теперь вы можете использовать 1-й вызов аргумента, чтобы заменить %1 на f.e. "#%3" и третий вызов аргумента для вставки номера.   -  person St0fF    schedule 02.06.2017


Ответы (3)


См. документы Qt о QString::arg(). :

QString str;
str = "%1 %2";
str.arg("%1f", "Hello"); // returns "%1f Hello"
person Johnny    schedule 09.03.2011
comment
Хорошо спасибо! И как поступить в случае, если вам нужны разные перегрузки QString::arg(), например. тоже по номерам? Использование QString::number() в multi-QString-arg() — это не то же самое, поскольку оно не дает вам возможности указать ширину поля. - person Tilman Vogel; 09.03.2011
comment
Хорошо, я мог бы использовать QString::leftJustified() или QString::rightJustified(), но это будет слишком долго. Я думаю, что иметь автоматически экранирующую версию arg() было бы здорово. - person Tilman Vogel; 09.03.2011
comment
@Джонни, QString("%1-%2").arg("%1").arg(23, 8, 10, QChar('0')); сделает QString("00000023-%2") вместо QString("%1-00000023"). - person Tilman Vogel; 09.03.2011
comment
@Tilman, что вы думаете об этом: QString(%1-%2).arg(%1, QString(%1).arg(23, 8, 10, QChar('0'))); ? - person Johnny; 09.03.2011
comment
@Johnny, да, не совсем ужасно ;-) Тем не менее грустно, это не работает в оригинальной элегантности ... Один из способов - избежать всех % в заменах и заменить их обратно после остановки душа arg (), используя некоторый промежуточный класс строкового шаблона. Спасибо за ваши мысли! - person Tilman Vogel; 10.03.2011

Обратите внимание, что перегрузка arg() для нескольких аргументов принимает только QString. Если не все аргументы являются QString, вы можете изменить порядок заполнителей в строке формата:

QString("1%1 2%2 3%3 4%4").arg(int1).arg(string2).arg(string3).arg(int4);

становится

QString("1%1 2%3 3%4 4%2").arg(int1).arg(int4).arg(string2, string3);

Таким образом, сначала заменяется все, что не является строкой, а затем одновременно заменяются все строки.

person Andreas Haferburg    schedule 15.09.2017

Вы должны попробовать использовать

QString("%1-%2").arg("%2","foo");
person user2665241    schedule 07.07.2015