最近在使用QString
的arg()
函数时遇到了这样一个隐藏的坑
通常使用QString
的arg()
函数时,都会是如下方式
QString str = "%1 or %2";
str = str.arg("a").arg("b");
qDebug() << str;
// str的结果是 a or b
但如果需要替换的字符串中包含"%+数字"时,就会出现问题,比如
QString str = "%1 or %2";
str = str.arg("%1").arg("b");
qDebug() << str;
// str的结果是 b or %2
在连续使用arg()
函数时,替换的时候是逐步进行替换的,所以第一个arg("%1")
替换后,就成了QString("%1 or %2").arg("b")
,当arg("b")
替换时,检测到字符串中还有%1
,于是就会替换掉,因此无法得到想要的结果
- Debug模式进行调试时也可以看到连续使用的
arg()
函数是逐个执行的
在Qt Assistant
中查询时发现arg()
的重载函数支持一次性替换
比如
QString str = "%1 or %2";
str = str.arg("%1", "b");
qDebug() << str;
// str的结果是 %1 or b
- 但这个重载函数最多只支持传入9个参数,且每个参数都必须是
QString
类型的字符串,大于9个参数的只能在后面继续跟arg()
进行处理,但那样就可能会遇到同样的问题 - 如果需要替换的字符串中无法避免"%+数字",且参数大于9个,可以分成多个字符串,然后拼接起来即可
以下是官方文档中的解释和例子,可做参考
This function overloads arg().
This is the same as str.arg(a1).arg(a2), except that the strings a1 and a2 are replaced in one pass. This can make a difference if a1 contains e.g. %1:
QString str;
str = "%1 %2";
str.arg("%1f", "Hello"); // returns "%1f Hello"
str.arg("%1f").arg("Hello"); // returns "Hellof %2"
A similar problem occurs when the numbered place markers are not white space separated:
QString str;
str = "%1%3%2";
str.arg("Hello").arg(20).arg(50); // returns "Hello500"
str = "%1%2%3";
str.arg("Hello").arg(50).arg(20); // returns "Hello5020"
Let's look at the substitutions:
* First, Hello replaces %1 so the string becomes "Hello%3%2".
* Then, 20 replaces %2 so the string becomes "Hello%320".
* Since the maximum numbered place marker value is 99, 50 replaces %32.
Thus the string finally becomes "Hello500".
In such cases, the following yields the expected results:
QString str;
str = "%1%2%3";
str.arg("Hello", QString::number(20), QString::number(50)); // returns "Hello5020"