You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用C++标准库对XML字符串进行反转义处理?

解决XML字符串反转义的问题

嘿,我来帮你搞定这个XML反转义的实现!首先先提个小问题:你现在的escape_XML函数里有几个语法错误——比如你用了chr == '"'这种写法,但chr是单个char类型,双引号应该直接写'"'或者\",单引号是'\'',&就是'&',这些是字符字面量,不是字符串转义哦。先把这个修正了,再来看反转义的实现。

对于unescape_XML,确实不能用简单的逐个字符遍历,因为转义序列是多字符的(比如&是5个字符)。我们可以用索引遍历,遇到&的时候就尝试匹配后续的转义序列,具体思路如下:

  • 用一个索引变量遍历输入字符串,而非范围for循环
  • 当遇到&时,查找后面最近的;,截取中间的标识部分(比如"中间的quot)
  • 根据标识匹配对应的原始字符,匹配成功就跳过整个转义序列,失败就保留&继续遍历
  • 非&的字符直接添加到输出

下面是修正后的完整代码:

#include <iostream>
#include <string>

std::string escape_XML(const std::string &input) {
    std::string output;
    output.reserve(input.size()); // 预分配空间提升性能
    for (char chr : input) {
        switch(chr) {
            case '"': output += "&quot;"; break;
            case '&': output += "&amp;"; break;
            case '<': output += "&lt;"; break;
            case '>': output += "&gt;"; break;
            case '\'': output += "&apos;"; break;
            default: output += chr; break;
        }
    }
    return output;
}

std::string unescape_XML(const std::string &input) {
    std::string output;
    output.reserve(input.size()); // 预分配空间
    const size_t len = input.size();
    size_t i = 0;

    while (i < len) {
        if (input[i] == '&') {
            // 查找当前&后面的第一个;
            size_t semicolon_pos = input.find(';', i);
            if (semicolon_pos != std::string::npos && semicolon_pos > i + 1) {
                // 截取&和;之间的部分
                std::string entity = input.substr(i + 1, semicolon_pos - i - 1);
                // 匹配转义实体
                if (entity == "quot") {
                    output += '"';
                    i = semicolon_pos + 1; // 跳过整个转义序列
                    continue;
                } else if (entity == "amp") {
                    output += '&';
                    i = semicolon_pos + 1;
                    continue;
                } else if (entity == "lt") {
                    output += '<';
                    i = semicolon_pos + 1;
                    continue;
                } else if (entity == "gt") {
                    output += '>';
                    i = semicolon_pos + 1;
                    continue;
                } else if (entity == "apos") {
                    output += '\'';
                    i = semicolon_pos + 1;
                    continue;
                }
            }
            // 如果没匹配到有效实体,就保留&,继续遍历
            output += input[i];
            ++i;
        } else {
            // 普通字符直接添加
            output += input[i];
            ++i;
        }
    }
    return output;
}

int main() {
    std::string input{ "\" <-> &quot;\n"
                       "& <-> &amp;\n"
                       "< <-> &lt;\n"
                       "> <-> &gt;\n"
                       "' <-> &apos;\n" };
    const std::string escaped = escape_XML(input);
    std::cout << "ESCAPED" << std::endl;
    std::cout << escaped;
    const std::string unescaped = unescape_XML(escaped);
    std::cout << "UNESCAPED" << std::endl;
    std::cout << unescaped;
    std::cout << std::flush;
}

代码说明:

  1. 修正后的escape_XML:用switch替代多个if-else更简洁,同时添加了reserve预分配输出空间,避免频繁内存分配提升性能。
  2. unescape_XML:
    • 用索引遍历,遇到&时查找后续的;,截取中间的实体名称
    • 匹配到有效实体就替换为对应字符,并跳过整个转义序列
    • 对于无效的实体(比如&abc;或者末尾没;的&),直接保留原始字符,避免破坏输入
  3. main函数:修正了字符串字面量的写法,确保测试用例正确。

这个实现完全基于C++标准库,没有依赖第三方工具,而且能处理各种边界情况,比如无效转义序列、字符串末尾的&等。

内容的提问来源于stack exchange,提问作者dumbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 15:43:11