代码之家  ›  专栏  ›  技术社区  ›  Thomas Sablik

在一行中替换多个字符串

  •  1
  • Thomas Sablik  · 技术社区  · 7 年前

    我有一个sql语句,为了调试,我想打印它。该语句包含占位符,我想在打印前将占位符填入一条指令行。这是有效的还是无效的?

    std::string query("SELECT A, B FROM C WHERE D = ? and E = ?;");
    std::cout << query.replace(query.find("?"), 1, "123").replace(query.find("?"), 1, "234") << std::endl;
    

    这是说明的顺序

    1. 找到第一个问号的位置
    2. 替换查询中的第一个字符串
    3. 查找第一次更换后第二个问号的位置
    4. 替换查询中的第二个字符串

    保证还是可能两者都 find 操作可以在两者之前调用 replace 像这样的行动

    1. 找到第一个问号的位置
    2. 在第一次更换前找到第二个问号的位置
    3. 替换查询中的第一个字符串
    4. 替换查询中的第二个字符串

    我这样问是因为:

    几乎所有C++算子操作数的求值次序 (包括函数参数在 函数调用表达式和 未指定任何表达式中的子表达式)。编译器可以 按任意顺序计算操作数,并且在 再次计算相同的表达式。

    编辑: 在这个项目中不可能使用第三方依赖关系。

    3 回复  |  直到 7 年前
        1
  •  3
  •   Jarod42    7 年前

    在里面 query.replace(query.find("?"), 1, "123").replace(query.find("?"), 1, "234")

    query.find("?") 相互之间没有顺序。 所以结果在可能的序列之间是不可预测的。

        2
  •  1
  •   patatahooligan    7 年前

    我在求值顺序规则中找不到任何严格规定链式函数的函数参数顺序的东西。也就是说,在你的情况下,你可以知道:

    1. 第一个 replace 在第二个之前排序,因为第二个根据其返回值进行操作

    2. 每个 find 调用在 代替 它使用其返回值作为参数

    但你想要的是第一次 代替 在第二个之前进行排序 发现 而且没有这样的保证。参考请参见规则 here .

        3
  •  1
  •   Maxim Egorushkin    7 年前

    你可以用 boost::algorithm::replace_first 多次:

    #include <boost/algorithm/string/replace.hpp>
    #include <iostream>
    #include <string>
    
    int main() {
        std::string query("SELECT A, B FROM C WHERE D = ? and E = ?;");
        for(auto replacement : {"123", "1"})
            boost::algorithm::replace_first(query, "?", replacement);
        std::cout << query << '\n';
    }
    

    请注意,这种简单的字符串替换对于需要引用的替换字符串不起作用。