JSON 字符串转义 / 反转义
JSON对 JSON 字符串进行转义与反转义——引号、控制字符与 \uXXXX。
本页内容
什么是 JSON 字符串转义?#
JSON 里的字符串必须包在一对双引号之间——这就带来一个麻烦:一旦文本本身就含有引号、换行或反斜杠,直接塞进去就会出问题。解析器要么把当中的引号误当成字符串的结尾,要么把反斜杠当成某个它不认识的转义的开头。转义(escape)就是把这些字符替换成规范定义的短反斜杠写法:引号写成 \",反斜杠写成 \\,换行写成 \n,制表符写成 \t,等等。反转义(unescape)则反过来,把这些序列还原成原始字符。
还有第二种更”狠”的模式。一些老系统——旧版日志采集器、挑剔的数据库、假定纯 ASCII 的传输层——遇到任何大于 127 的字节就崩。对它们来说,JSON 允许把任意非 ASCII 字符写成 \uXXXX 的形式(高于 U+FFFF 的字符比如 emoji 则写成 UTF-16 代理对)。这样得到的仍然是合法 JSON,只是转义之后整段全由 ASCII 组成。
本页两个方向、两种模式都支持:把原始文本转义成合法的 JSON 字符串字面量,或者把字面量反转义回原文——再加上一个可选的 ASCII-only 开关,强制把每个非 ASCII 字符都变成 \uXXXX 写法。
怎么使用#
- 用工具栏左上角的 编码 / 解码(Encode / Decode)开关选好方向。编码把原始文本转成 JSON 字面量;解码把字面量还原成文本。
- 在左侧 输入 框里输入或粘贴。
- 编码 模式下,整段文本会变成一个 JSON 字符串字面量(外层双引号包含在内)。
- 解码 模式下,你既可以粘贴带引号的字面量(
"a\nb"),也可以只粘贴里头那串转义体(a\nb)——工具会自动补上外层引号。如果粘进来的是合法 JSON 但不是字符串(比如一个裸数字、布尔值或对象),工具会直接报”不是字符串”,而不是偷偷帮你强转。
- 当下游消费方处理不了非 ASCII 字节时,勾上 仅 ASCII 输出(\uXXXX)(编码模式下)。emoji 这类辅助平面字符会被正确地写成代理对,和
JSON.stringify的行为完全一致。 - 右侧 输出 框会实时显示结果,点 复制(Copy)取走。
- 点 示例(Sample)载入一段多语言演示文本;点 清空(Clear)重置两边。
主要特性#
- 严格符合规范的短形式。 用的是 RFC 8259 规定的那几个序列(
\"、\\、\b、\f、\n、\r、\t),其余小于 0x20 的字符一律用\uXXXX——和JSON.stringify逐字节对齐。 - 真正的 ASCII-only 模式。 非 ASCII 字符不会被悄悄丢掉或变成乱码,而是逐个输出为
\uXXXX;辅助平面字符(高于 U+FFFF)会被正确拆成 UTF-16 代理对,而不是一个会让解码器报错的孤立码元。 - 宽容的反转义。 既接受完整带引号的字面量,也接受裸转义体——从日志里半截复制出来的片段也能解开,不至于直接抛错。
- 拒绝替你猜。 如果解码输入是合法 JSON 但不是字符串(比如裸数字或数组),工具会明明白白告诉你,而不是在背后偷偷帮你 stringify。
实例演示#
在 编码 模式下点 示例,输入是一段故意混了引号、反斜杠路径、换行、版权号、emoji 和中文的文本:
He said "hi"
\path\ © 🌍 你好
不勾 ASCII-only 时,转义后的字面量会保留可读字符原样,只转义必须转义的:
"He said \"hi\"\n\\path\\ © 🌍 你好"
现在勾上 仅 ASCII 输出(\uXXXX),同一段输入就变成纯 ASCII——版权号收缩为四位形式 \u00a9,地球 emoji 变成代理对 \ud83c\udf0d,每个汉字变成各自的码点(\u4f60、\u597d):
"He said \"hi\"\n\\path\\ \u00a9 \ud83c\udf0d \u4f60\u597d"
切到 解码,把上面任意一段字面量粘回去:原文一字不差地还原,emoji 和中文都在。
常见问题#
为什么 emoji 变成了两个 \u 码,而不是一个?#
高于 U+FFFF 的字符(emoji、罕见的 CJK 扩展汉字、部分数学符号)塞不进一个 16 位码元,所以 UTF-16 用一个代理对来表示它——一个高位代理加一个低位代理。地球 emoji 🌍(U+1F30D)会变成 \ud83c\udf0d。如果只输出一个 \u,得到的是非法 JSON,严格的解码器会拒绝;本工具和 JSON.stringify 一样输出完整的代理对,所以结果能原样往返。
解码时报”输入不是 JSON 字符串”,我粘的是什么?#
你粘的东西虽然是合法 JSON,但并不是字符串——通常是一个裸数字(42)、布尔值(true)或者对象/数组。工具拒绝替它 stringify,因为那会掩盖一个真实的失误(你几乎肯定是想粘字符串值,而不是整个文档)。给文本加上引号再试一次。
能处理制表符、响铃这类控制字符吗?#
能。输入里的制表符会变成 \t,退格 \b,换页 \f,回车 \r;其他任何小于 U+0020 的控制码(包括响铃 0x07)都会变成对应的 \u0007 形式。这点很关键,因为原始控制字符在 JSON 字符串里是非法的,有些解析器会直接拒收。
ASCII-only 输出更”安全”吗?#
只对一种安全有意义:穿过一个会改写或拒收非 ASCII 字节的传输层时它能活下来。它不是加密、不是安全措施——数据仍然完全可逆,只是换了一套更受限的字母表来表示。下游要求 ASCII 时才勾上;否则关掉,可读的形式调试起来轻松得多。