小编典典

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

algorithm

我简直不敢问这个问题。我有一个字符串,需要将其插入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();
    };
}

阅读 286

收藏
2020-07-28

共1个答案

小编典典

您不仅可以替换原始字符串,还可以通过即时替换来进行复制,从而避免了必须移动字符串中的字符。这将具有更好的复杂性和缓存行为,因此,我希望会有很大的改进。或者,您可以使用boost
:: spirit :: xml编码
http://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);
}

编辑:
使用启发式方法确定缓冲区的大小可以实现小幅改进。buffer.reservedata.size()*1.1(10%)或类似的东西代替生产线,具体取决于预期的替换量。

2020-07-28