中文转义
中文与 \uXXXX 转义、HTML 数字实体、URL 百分号编码互转,顺便把「看起来像拉丁字母」的乱码还原回中文。
输入
输出
四种写法,同一个字
很多通道只保证 ASCII 安全:HTTP 头、Cookie、老式日志系统、Java 的 properties 文件、只认 US-ASCII 的构建脚本。中文要安全穿过这些通道,就得先「ASCII 化」。常见做法有四种,本质都是把字符换成能在任何地方原样传输的字符组合。
| 写法 | 「中文」的样子 | 常见于 |
|---|---|---|
| 原始文本 | 中文 | 页面、终端、现代编辑器 |
| Unicode 转义 | \u4e2d\u6587 | JSON / JS 字符串字面量、Java 源码、部分日志 |
| HTML 实体 | 中文 或 中文 | HTML 源码、老邮件模板 |
| URL 百分号 | %E4%B8%AD%E6%96%87 | URL 查询串、表单、Cookie |
三者的数字并不通用:转义写的是 UTF-16 码元,HTML 实体写的是 码点,百分号编码写的是 UTF-8 字节。同一个「中」字,转义是 4e2d,实体是 20013,百分号是三组字节 E4 B8 AD——改格式必须整个转换,不能只换前缀。
emoji 为什么要写成两个 \uXXXX
Unicode 转义按 UTF-16 码元书写,每四位一组。码点超过 U+FFFF 的字符(emoji、部分生僻字)在 UTF-16 里要占两个码元,所以一个 🐟 会写成 \ud83d\udc1f 两组,看起来像两个字符,其实是一个。解码时它们会自动拼回一个完整的字符。HTML 实体则直接写码点,🐟 是 🐟,一个实体就够。所以同一个 emoji 在两种写法里的长度完全不同,这不是工具算错了。
中文乱码的三种成因
- 编码不一致(GBK 与 UTF-8 互相误读)。字节按一种编码写、却按另一种读。看到「锟斤拷」这类说明原始信息已经丢失(错误字节被替换成了固定字符),任何工具都还原不了;看到「䏿–‡」这类拉丁字母混排,说明是 UTF-8 被当成 Latin-1 或 Windows-1252 读了,勾选「先修复 UTF-8 乱码」即可还原。
- Unicode 转义没有被解释。接口返回的是
\u4e2d\u6587字面量,前端原样打印到页面上。把输入格式选成 Unicode 转义,输出格式选纯文本。 - URL 百分号编码没有被解码。链接里的
%E4%B8%AD被原样抄进了文档或日志。选 URL 百分号编码 → 纯文本,或者去用 URL 编解码。
已知边界
HTML 实体只解码数字实体(十进制与十六进制)和一小批常见命名实体(amp、lt、gt、quot、nbsp、copy、hellip 等),其余命名实体原样保留,不会被误改。GBK / GB18030 造成的乱码不在本工具能力范围内。
常见问题
为什么一个 emoji 会变成两个 \uXXXX?
因为 Unicode 转义按 UTF-16 码元写,而 emoji 的码点大于 U+FFFF,UTF-16 需要两个码元(代理对)。这是规范行为,Java、JavaScript、JSON 都这么写,解码时会自动还原。
\u4e2d、中、%E4%B8%AD 有什么区别?
三者分别用 UTF-16 码元、码点、UTF-8 字节表示同一个字,数字都不一样,不能只换前缀。要跨格式转换,用这个工具在四种格式之间互转,不要手工替换。
乱码看起来像拉丁字母,能还原吗?
能。像「䏿–‡」这种是 UTF-8 字节被当成 Latin-1 / Windows-1252 读出来的,勾选「先修复 UTF-8 乱码」就会先按字节还原再转换。这类乱码串中间夹着一个不可见的软连字符(就是上面的
­),复制时被丢掉的话就还原不了。HTML 实体输出用十进制还是十六进制?
默认十进制,例如输出
中;勾选「HTML 用十六进制」后输出 中。两种浏览器都认,选哪个主要看团队习惯。「仅转义非 ASCII」是干什么的?
默认开启,只转义中文等非 ASCII 字符,英文数字和标点保持原样,输出还能直接读。关掉之后每个字符都会被转义。