使用方法
- 「NDJSON 源文本」默认已经写好五行:每行一个完整 JSON 值,第一行的 note 里有一个反斜杠 n 转义,第四行的 tags 是嵌套数组,第五行的 extra 是 null。
- 点「开始转换」,或在文本框里按 Ctrl+Enter(Mac 是 Cmd+Enter)完成转换;在「数组输出缩进空格数」输入框里按回车同样触发。
- 「转换方向」默认 NDJSON → JSON 数组,粘贴 .jsonl、.ndjson 日志文件时用这个方向;改成 JSON 数组 → NDJSON 时,输入的是一整个 JSON 数组,输出为每个元素一行。
- 「数组输出缩进空格数」默认 2,可填 0 到 8 的整数,只在 NDJSON → 数组方向有效;填 0 输出压缩成一行。反方向每行永远是紧凑单行,这是格式本身的要求。
- 结果区第一行是统计摘要:物理行数、跳过的空行数、有效行数与元素个数;下面是输出原文,「复制结果」复制的就是这段原文。
- 输入框被清空时点「开始转换」会自动填回示例;本页不联网,也不写 localStorage,刷新即恢复默认。
- 下方是十九行行形对照表,默认显示 12 行,点「加载更多」看余下 7 行;「导出 CSV」存成带字节序标记的文件,「复制对照表」复制成制表符分隔文本。
- 空行与纯空白行会被跳过并在摘要里计数;尾随换行不会多出一个空元素,最后一行之后没有内容也照样输出。
这个JSON行转换器能解决什么
把 NDJSON 转成 JSON 数组,或把 JSON 数组拆成一行一个值——这个JSON行转换器两个方向都做。NDJSON 的典型场景是日志:每行一条事件,写盘时追加一行即可,崩溃时最多损失最后一行;Elasticsearch 的 bulk API 要求请求体按 NDJSON 组织;BigQuery 等数仓导出也常用这种格式。
第一类需求是校验与查看。日志文件动辄几万行,直接粘进通用 JSON 工具会因为「整体不是合法 JSON」而报错。本页逐行 parse,哪一行有问题就报第几行,其余行照常输出,几十万行也能快速定位到第一条坏行。
第二类需求是反向打包。手上有前端传来的 JSON 数组,要喂给 bulk API 或写成 .jsonl 文件,就得把每个元素压成一行。本页反向输出时每个元素都是紧凑单行,行间只用一个真实换行分隔,不再加任何缩进——加了缩进,一个值就跨了多个物理行,下游按行读的代码会全部失效。
边界也要说清:本页只做切分与重组,不做 schema 校验、不去重、不改键名,值原样保留。超大文件受浏览器内存与粘贴长度限制,几十兆以上的日志建议先用命令行工具处理。
切分原理与变量说明
切分器是一个认得引号状态的扫描器:逐字符走一遍输入,维护「是否处于字符串内」与「前一个字符是不是反斜杠」两个状态。只有在字符串外遇到的真实换行才断行;字符串里出现的反斜杠加 n 是两个普通字符,代表 JSON 的换行转义,不是物理换行。Windows 文本常见的回车加换行(CRLF)被当成一个行尾。
断行之后,每一行先去掉首尾空白;空行与纯空白行直接跳过并计数;其余行先经过一道自有检查——用同样的字符串感知扫描找出第一个完整值的结束位置,若后面还有内容就报「一行只能有一个值」,括号或引号没闭合也在这道检查里报错——通过后才交给 JSON.parse 做真正的语法校验。两层检查让每条报错都能指到第几行、什么原因。
数组与 NDJSON 的根本差别在流式能力:JSON 数组的最后一个右方括号出现之前,任何前缀都不是合法 JSON,必须整体读完后才能处理第一条;NDJSON 每行独立,读一行就能解析一行,内存占用与同时处理的行数成正比,而不是与文件总体积成正比。这也是日志系统偏爱 NDJSON 的原因。
反向转换把每个元素 JSON.stringify 之后用一个真实换行连接。这里有一个容易踩的坑:不要给每行加缩进。pretty-print 会让一个值跨多个物理行,按行读取的消费者读到的是半行 JSON,格式性质被破坏,因此本页不提供「每行格式化」选项。
| 变量 | 含义 | 取值 | 影响 |
|---|---|---|---|
| dir | 转换方向 | nd / arr | 决定用切分器还是整体 parse |
| ind | 数组输出缩进 | 0 ~ 8 的整数 | 仅 nd 方向有效,0 时压缩成一行 |
| iq | 字符串状态 | true 表示处于字符串内 | 为 true 时遇到真实换行即报错 |
| esc | 转义状态 | true 表示前字符是反斜杠 | 为 true 时引号不当收尾 |
| blank | 空行计数 | 非负整数 | 摘要里报告跳过了多少行 |
完整示例
默认的五行源文本每行都是一个完整值。第一行的 note 字段里写着反斜杠加 n,它是 JSON 的换行转义,扫描器不会在这里断行;第四行的 tags 是嵌套数组,转成 JSON 数组后会跟着多级缩进展开;第五行的 extra 是 null,转成数组后仍是 null,不会变成字符串 "null"。
{"id":1,"name":"Alice","note":"第一行\n含转义换行"} → 第 1 行,反斜杠 n 不断行
{"id":2,"name":"Bob","score":95.5} → 第 2 行,数字保持 number
{"id":3,"name":"Carol","ok":true} → 第 3 行,布尔保持 boolean
{"id":4,"name":"Dave","tags":["x","y"]} → 第 4 行,嵌套数组原样进入
{"id":5,"name":"Eve","extra":null} → 第 5 行,null 保持 null
把「数组输出缩进空格数」改成 0,五行会输出成一个单行数组;改成 4 则每级多两个空格。把「转换方向」改成 JSON 数组 → NDJSON,再粘贴一个两元素的数组,输出是两行,每行一个紧凑 JSON 值。把第一行的反斜杠 n 换成真实的换行键,会报「第 1 行附近:字符串里出现未转义的真实换行」。
NDJSON 行形对照表
下表列出十九种行形经过本页切分与解析后的结果,由页面自己的切分器与 JSON.parse 逐条算出,前十二行直接展开,点工具区的「加载更多」看余下八行。报错行给出的是完整错误文案。
| 行形 | 解析结果 | 说明 |
|---|---|---|
| {"a":1} | 1 个元素 · 首个 object | 一行一个对象 |
| [1,2,3] | 1 个元素 · 首个 array | 行可以是数组 |
| "hello" | 1 个元素 · 首个 string | 裸字符串 |
| 42 | 1 个元素 · 首个 number | 裸数字 |
| true | 1 个元素 · 首个 boolean | 裸布尔 |
| null | 1 个元素 · 首个 null | 裸 null |
| {"a":1} | 1 个元素 · 首个 object | 行尾空白忽略 |
| {"a":"x\ny"} | 1 个元素 · 首个 object | 反斜杠n不是换行 |
| {"a":1}{"b":2} | 报错:第 1 行:第一个完整值之后还有内容「{"b":2}」,一行只能有一个值。 | 一行两值报错 |
| [] | 1 个元素 · 首个 array | 空数组也是一行 |
| {"a":1e3} | 1 个元素 · 首个 object | 科学计数法合法 |
| {"a":1 | 报错:第 1 行:括号没全部闭合,不是完整 JSON 值。 | 括号没闭合 |
第二张表对照三种输入形态,说明为什么只有第一种能安全按行切分。
| 输入形态 | 按行切分是否安全 | 原因 |
|---|---|---|
| NDJSON(每行一个完整值) | 安全 | 每行独立可解析,读一行就能处理一行 |
| pretty-print 的 JSON 数组 | 不安全 | 一个值跨多个物理行,按行切出来都是半行 |
| 压缩成一行的数组 | 合法但只有一个元素 | 整行被当成一个值,不会自动拆开 |
| 字符串里含真实换行 | 报错 | JSON 字符串不允许未转义的物理换行 |
结果边界与错误提示
- 源文本整段为空或只有空白时,提示「NDJSON 源文本这一栏是空的」,不会输出空数组;点「开始转换」会自动填回示例。
- 反方向输入为空时提示「JSON 源文本这一栏是空的,请粘贴一个 JSON 数组」,指明需要的是数组而不是单个值。
- 反方向输入合法但不是数组时,提示解析结果是对象还是标量,并说明只有一条记录时请包一层方括号。
- 某一行不是合法 JSON 时,提示第几行与解析器给出的原因;括号未闭合、字符串未闭合在交给 JSON.parse 之前就被自有扫描器截获,报错更早。
- 一行里出现两个值时,提示「第一个完整值之后还有内容」,并把多余内容引出来——这是把紧凑数组错粘进本页的最常见形态。
- 空行与纯空白行跳过并在摘要计数;尾随换行不产生空记录;空数组在反方向输出为零行,不是一行 "[]"。
- 输出 JSON 数组时不带字节序标记,导出的 .json 文件同样不带 BOM;只有对照表的 CSV 导出带 BOM,两者刻意相反。
- 本页不做类型转换:数字、布尔、null 在两种格式间原样搬运,不会出现 "true" 这种字符串化结果。
常见问题
NDJSON 和 JSON 数组到底差在哪?
JSON 数组是一个值:方括号包住若干元素,必须整体 parse 完才能取出第一条。NDJSON 是若干行,每行一个完整值,行与行之间只靠真实换行分隔,可以读一行解析一行。差别在读取方式与内存曲线。
为什么不能直接按换行 split?
因为换行有两种形态:真实换行(行尾)与反斜杠 n 转义(字符串里的两个字)。直接 split 会把字符串里的转义当成行尾;先反转义再切会把值改掉。本页用认得引号状态的扫描器,只在字符串外的真实换行处断行。
尾随换行会多出一个空元素吗?
不会。最后一行之后的换行只产生一个空行,空行被跳过并计入摘要的「空行或纯空白行」,不会成为数组里的 null 或空对象。
pretty-print 的 JSON 能粘进来吗?
不能按行处理。一个 pretty-print 的对象或数组跨多个物理行,本页会报「括号没全部闭合」或「一行里有两个值」。要转的话,请先用格式化工具把它压成一行,或改用 JSON 数组 → NDJSON 方向。
反向转换时能不能每行也格式化?
不能,也不该。给每行加缩进会让一个值跨多个物理行,按行读取的 bulk API 与日志消费者读到的是半行 JSON。NDJSON 的定义就是每行一个完整值,紧凑单行是硬要求。
NDJSON 常见用在哪些地方?
三类最常见:应用日志(每行一条事件,追加写、崩溃少丢数据)、Elasticsearch bulk API(索引与删除操作按行组织)、数仓导出(BigQuery 等支持按行流式读取大结果集)。
一行里有两个值为什么会报错?
因为 NDJSON 规定一行只能有一个完整值。一行里出现两个值,说明要么是把两行粘成了一行,要么是把压缩数组错当了 NDJSON。本页报「第一个完整值之后还有内容」并把多余部分引出来,方便回退改正。
导出的文件带 BOM 吗?
JSON 输出与 .json 文件都不带字节序标记,避免下游解析器把 BOM 当成语法错误;只有对照表的 CSV 导出带 BOM,这是给 Excel 开门用的。
相关工具
- JSON格式化工具:把紧凑 JSON 展开成多行查看。
- JSON校验工具:逐字符定位错误行号与中文原因。
- JSON压缩工具:去掉多余空白压成单行。
- CSV转JSON转换器:把表格数据转成对象数组。
- YAML转JSON转换器:处理带缩进与类型的配置格式。