piapia123
zh

JSON5 → JSON

格式化

所有处理都在浏览器本地完成,数据不上传服务器

输入
把文件拖到这里可直接载入
输出

把一份 JSON5 解析成标准 JSON。JSON5 是 JSON 的超集,多了注释(`//` 与 `/* */`)、无引号的键(含中文标识符)、单引号字符串、尾逗号、十六进制数字、前导 `+`、省略整数位或小数位的写法(`.5` / `5.`),以及 `Infinity` 与 `NaN` —— 各种配置文件(VS Code、Babel、TypeScript、ESLint 的一部分)都在用它,而很多工具只接受严格 JSON。 只有一个方向,这是有理由的:JSON 本来就是 JSON5 的子集,所以「JSON → JSON5」是一次恒等变换。做成一个选项只会让人以为它会顺手做点别的(加注释?换单引号?)。需要那个方向的话,标准 JSON 本身就是合法的 JSON5 文档,直接拿去用。 解析是完整的实现,不是「够用」的子集 —— 语法边角(`\x41`、`\u{1F600}`、行继续符、`+Infinity`)都按规范处理,出错时给出行与列。 ⚠️ 两处已知的转换损失,都写在下面:JSON 表达不了 `Infinity` 与 `NaN`,它们会变成 `null`;字符串之间不会有问题,但注释是肯定留不下的(JSON 里没有放注释的地方)。

功能

  • 注释:`//` 行注释与 `/* */` 块注释,出现在的任何位置都能处理
  • 无引号的键,包括中文与 `$` `_` 开头的标识符
  • 单引号字符串(里面可以直接放双引号,不用转义)
  • 尾逗号:对象、数组、嵌套结构都认
  • 十六进制 `0xFF`、前导 `+`、省略整数位 `.5`、省略小数位 `5.`
  • `Infinity`、`-Infinity`、`NaN`(JSON 没有这三个值)
  • `\x41`、`\u{1F600}`、行继续符这些转义按规范处理
  • 解析错误指出具体的行与列,而不是一句「格式不对」
  • ⚠️ `__proto__` 作为键名时会成为普通属性,不会污染原型
  • 输出是标准 JSON,能被任何只认 JSON 的工具读走

使用方法

  1. 把 JSON5 粘进输入框 —— 有注释、无引号键、尾逗号都行
  2. 结果实时出现
  3. 选缩进方式,或压成一行
  4. 点复制取走结果

常见问题

为什么没有「JSON 转 JSON5」这个方向?
因为它是一次恒等变换。JSON5 是 JSON 的严格超集(这正是它的设计目标),所以任何合法的 JSON 文档本身就是合法的 JSON5 文档 —— 不需要转换。真做成一个按钮的话,它会要么什么都不做(让人以为坏了),要么自作主张加些东西(去掉键的引号、换成单引号),而那些都是风格选择,不该由工具替用户决定。
注释去哪了?
丢掉了,而且只能丢掉:JSON 的语法里没有可以承载注释的地方,标准 JSON 不允许注释。这是格式之间的差异,不是实现的取舍。如果你的 JSON5 里那些注释很重要(配置说明、被注释掉的开关),建议保留一份原始文件,不要把它当作一次性的中间产物。
Infinity 和 NaN 变成 null 了,这算 bug 吗?
不算,但也确实是个损失 —— JSON 根本没有办法表示它们。`JSON.stringify(Infinity)` 的结果就是 `null`,这是语言层面的行为,任何输出标准 JSON 的工具都一样。JSON5 允许写 `Infinity` / `NaN` 是它的扩展,而标准 JSON 没有对应的语法。如果你的数据里有这两个值,需要的是「用字符串 `"Infinity"` 表示」这种约定,那得由消费方一起约定,工具单方面改不了。
解析器是自己写的还是用了库?
自己写的。理由与 YAML / TOML 那两个工具相反:那两个的复杂度来自「同一句话有十种写法」,自己写必然在某个输入上静默解析成别的意思,所以要引成熟的库;而 JSON5 的语法是封闭且冻结的(2018 年的 1.0 之后再没改过),只是在 JSON 之上加了注释、无引号键、单引号、尾逗号这几样,完整实现是可控的。正确性由一条差分测试兜底:凡是合法 JSON 的输入,本解析器的结果必须与 `JSON.parse` 逐字段相同。

相关工具