DevTool 团队

Unicode 解码与乱码自救:\u 转义是什么、怎么还原

收到一串 \u4f60\u597d 或者 &#x 的字符看不懂?本文分清 \u 转义、码点、HTML 实体、URL 编码四种形态,给出还原成中文的代码方法与在线工具,并讲清 Emoji 代理对的坑。

先分清你手里的乱码是哪一种

「乱码」不是一种东西,是四种。还原之前先看形态,形态决定方法:

形态 长什么样 它是什么
Unicode 转义 \u4f60\u597d 按码点转义,JSON / JS 源码 / 部分接口的默认输出
码点形式 U+4F60 或 4f60 字符在 Unicode 表里的编号本身
HTML 实体 你 或 你 HTML 里的字符引用,十六进制与十进制两种写法
URL 编码 %E4%BD%A0%E5%A5%BD 按 UTF-8 字节逐个百分号转义,一个中文三个 %XX

\u4f60\u597d 解开是「你好」,你 解开也是「你」,%E4%BD%A0 解开还是「你」——同一批字符、三层编码。混着出现(比如 URL 参数里包着转义过的 JSON)就一层一层剥。

方法一:在线工具,看不清形态时最省事

Unicode 编码解码工具支持上面四种形态的互转,并带两个排查时特别有用的能力:

  1. 自动识别输入格式——不确定手里是转义、实体还是百分号编码时,直接粘贴,它按特征判断;
  2. 字符详情面板——每个字符的码点、十进制、十六进制、UTF-8 字节、分类信息逐项列出,乱码到底是编码问题还是字体问题,看一眼详情就能定位。

统计区实时显示字符数与字节数,「一列到底占了多少字节」这种问题不用再心算。转换历史存在本地,来回对比两段文本时可以回翻。

方法二:用代码还原

知道数据来源、想嵌进脚本里处理时,两行代码的事。

JavaScript——JSON 里的 \u 转义在 JSON.parse 时自动解开:

JSON.parse('{"msg":"\\u4f60\\u597d"}').msg;  // "你好"

普通字符串里的转义,console.log 本身就会渲染;要把任意字符反向转成 \u 形式,charCodeAt(0).toString(16) 拼四位即可。

Python——unicode_escape 编解码器专治这个:

s = r"\u4f60\u597d"
print(s.encode().decode("unicode_escape"))  # 你好

URL 编码则是另一套:urllib.parse.unquote("%E4%BD%A0")。两者经常叠着出现,先解外层再解内层。

反向:什么时候需要「编码」而不是解码

  • 接口或配置文件只接受 ASCII,中文明文过不去——整段转成 \u 转义;
  • 要在 HTML 里安全展示特殊字符(<、&、不可见字符)——转 HTML 实体;
  • 拼接 URL 参数——中文必须百分号编码,否则请求直接报错;
  • 排查「这个字符到底是什么」——转成码点形式,去 Unicode 表里查它的分类与名称。

本站工具的输入输出可以一键交换,反向操作不用换工具。

Emoji 与代理对:逐字解码的坑

「😀」的码点是 U+1F600,超出了 U+FFFF。UTF-16 用一对代理项表示它:\ud83d\ude00。问题来了:

  • 逐字符解码的简易工具会把这对代理拆成两个「字符」,输出两个问号或两个方块;
  • 按码点逐个统计的代码会把一个 Emoji 数成 2 个字符;
  • 字符串截断如果切在代理对中间,前后都会烂。

判断一个工具能不能信,丢一个 Emoji 进去就知道了。本站的转换按代理对正确处理,U+FFFF 以上的字符不会被拆碎;字符统计同样按完整字符计数。

常见问题

\u4f60\u597d 这种字符串是什么编码?

这是 Unicode 转义序列,每个 \u 后跟四个十六进制位,表示一个字符的码点。\u4f60\u597d 解码后就是「你好」。它常见于 JSON、JavaScript 源码和部分接口返回,本质仍是 UTF-8 文本,只是把非 ASCII 字符写成了转义形式。

为什么有的 Emoji 解码后会变成两个字符?

因为它们超出了基本多文种平面(U+FFFF 以上),UTF-16 里要用一对代理项(Surrogate Pair)表示,占两个码点位置。逐字解码的工具会把一个 Emoji 拆成两个乱码字符;支持代理对的工具能正确合并还原。

\u 转义和百分号编码(%E4%BD%A0)是一回事吗?

不是。\u 转义按码点表示字符;百分号编码是 URL 编码,按 UTF-8 字节逐个转义,一个中文通常是三个 %XX。两者经常同时出现在同一段数据里,但编码层级不同,解码顺序也不同。

怎么把一段文本反向编码成 \u 转义形式?

在 Python 里用 "你好".encode("unicode_escape"),或本站工具的编码方向一键得到;JavaScript 里 JSON.stringify 对非 ASCII 字符默认就会输出 \u 转义。接口只收转义形式、或要压缩非 ASCII 字符可见度时用得上。

在线解码会把内容传到服务器吗?

本站的 Unicode 转换在浏览器本地完成,输入不离开设备,转换历史也只存在浏览器里。使用其他在线工具前应确认其数据处理方式,含敏感内容的文本尤其要注意。

相关阅读