在C++字符串中转义XML/HTML的最有效方法?

pap*_*jam 30 c++ string algorithm stl

我不敢相信以前没有问过这个问题.我有一个字符串需要插入HTML文件,但它可能包含特殊的HTML字符.我想用适当的HTML表示替换它们.

下面的代码有效,但非常冗长和丑陋.性能对我的应用程序并不重要,但我想这里也存在可伸缩性问题.我怎样才能改善这个?我想这是STL算法或一些深奥的Boost函数的工作,但下面的代码是我能想出的最好的代码.

void escape(std::string *data)
{
    std::string::size_type pos = 0;
    for (;;)
    {
        pos = data->find_first_of("\"&<>", pos);
        if (pos == std::string::npos) break;
        std::string replacement;
        switch ((*data)[pos])
        {
        case '\"': replacement = "&quot;"; break;   
        case '&':  replacement = "&amp;";  break;   
        case '<':  replacement = "&lt;";   break;   
        case '>':  replacement = "&gt;";   break;   
        default: ;
        }
        data->replace(pos, 1, replacement);
        pos += replacement.size();
    };
}
Run Code Online (Sandbox Code Playgroud)

Gio*_*hal 40

您可以使用即时替换进行复制,而不必仅仅替换原始字符串,从而避免必须在字符串中移动字符.这将具有更好的复杂性和缓存行为,因此我期望得到巨大的改进.或者您可以使用boost :: spirit :: xml encodehttp://code.google.com/p/pugixml/.

void encode(std::string& data) {
    std::string buffer;
    buffer.reserve(data.size());
    for(size_t pos = 0; pos != data.size(); ++pos) {
        switch(data[pos]) {
            case '&':  buffer.append("&amp;");       break;
            case '\"': buffer.append("&quot;");      break;
            case '\'': buffer.append("&apos;");      break;
            case '<':  buffer.append("&lt;");        break;
            case '>':  buffer.append("&gt;");        break;
            default:   buffer.append(&data[pos], 1); break;
        }
    }
    data.swap(buffer);
}
Run Code Online (Sandbox Code Playgroud)

编辑:通过使用启发式来确定缓冲区的大小,可以实现小的改进.根据预期的替换次数,buffer.reservedata.size()*1.1(10%)或类似的替换线.


pap*_*jam 6

void escape(std::string *data)
{
    using boost::algorithm::replace_all;
    replace_all(*data, "&",  "&amp;");
    replace_all(*data, "\"", "&quot;");
    replace_all(*data, "\'", "&apos;");
    replace_all(*data, "<",  "&lt;");
    replace_all(*data, ">",  "&gt;");
}
Run Code Online (Sandbox Code Playgroud)

可以赢得奖项至少冗长吗?

  • 您的实施也应该赢得表现最差的奖项,因为它将编码N长串的&符号/引号/等.在O(N ^ 2)复杂度. (5认同)
  • 关心订单,你应该从"&"开始:-) (3认同)