JSON中允许多行字符串吗?

1145

JSON格式中是否可以有多行字符串?

我想主要是为了视觉上的舒适性,所以我可以在编辑器中打开自动换行功能,但我只是有些好奇。

我正在使用JSON格式编写一些数据文件,并希望将一些非常长的字符串值拆分为多行。使用Python的JSON模块时,无论我使用\还是\n作为转义字符,都会出现很多错误。


4
结构化你的数据:将多行字符串分割成字符串数组,稍后再将它们合并。 - RubyTuesdayDONO
3
试用hjson工具,它可以将你的多行字符串转换为正确的JSON格式。 - Gaurav
1
可能是重复的问题:JSON 值可以包含多行字符串吗? - Jonathan Hall
如果您有一个长字符串需要编码,以便将其作为JSON字符串传递,请在网上搜索JSON编码器,例如https://nddapp.com/json-encoder.html。 - ozhug
15个回答

643
很不幸,这里的很多答案都是回答如何在字符串数据中插入换行符。问题是如何通过将字符串值跨越代码的多行来使代码看起来更好。即使是那些认识到这一点的答案也提供了“解决方案”,假定一个人可以自由改变数据表示,但在许多情况下一个人是不能这样做的。 更糟糕的消息是,没有好的答案。在许多编程语言中,即使它们没有显式支持跨行拆分字符串,您仍然可以使用字符串连接来实现所需的效果;只要编译器不太差,这就没问题。但是 JSON 不是一种编程语言;它只是一种数据表示形式。您无法告诉它连接字符串。 它(相当小的)语法也不包括任何表示字符串跨多行的设施。除了设计某种预处理器之外(而我不想创造自己的语言来解决这个问题),没有通用解决方案。如果您可以更改数据格式,则可以替换为字符串数组。否则,这是 JSON 不适合人类可读性的众多方式之一。

4
不清楚原帖作者想要什么,是想在字符串中增加换行符还是更好地组织字符串…… - 9ilsdx 9rvj 0lo
16
这是提问者真正想要的正确答案,我也是如此,即使JSON格式化工具的结果看起来不太令人满意... - Xiang
35
太棒了,这正是我在寻找的答案,此外,提醒JSON不是一种语言有助于将问题置于相应的背景中。 - Tim Heilman
20
非常清楚OP所问的内容,并且这是正确的答案。 - Steven P
21
有时候我会觉得 JSON 格式的设计不够完善。没有注释,也没有多行支持。我知道它只是一种数据格式,但是它是“供人使用”的。因此,一些“人性化”的功能会很有帮助。 - dvdmn
显示剩余6条评论

621

JSON 不允许真正的换行。你需要用 \n 替换所有换行。

例如:

"first line
second line"

可使用以下方式保存:

"第一行\n第二行"

注意:

对于Python,应写成:

"第一行\\n第二行"

其中\\是用于转义反斜杠的,否则python将把\n视为控制字符"新行"


121
OP正在使用"\n"转义序列,但由于他们没有将反斜杠作为"\n"进行转义,所以它没有起作用。Python会将转义序列转换为换行符,而不是像JSON所需的字面上带有反斜杠后跟en的字符。 - user359996
7
对于我来说(使用JSON存储数据,只有\n并通过Curses输出),\n似乎可以正常工作。这似乎取决于视图/渲染引擎是否支持。 - ashes999
7
@Nawaz: "\n" 和 "\r" 分别是换行和回车的转义序列。它们不是文字上的换行和回车控制字符。为了更清晰地举例说明,考虑到 "\" 是反斜杠的一个转义序列,而不是字面上的反斜杠。JSON语法在“char”定义中明确排除了控制字符,并通过转义序列(\、\r、\n等)来表示它们。 - user359996
11
OP并不想“表示”新行,而是想在多个源代码行上格式化一条逻辑JSON行。他通过谈论\n而让事情变得混乱了。他想要的是旧时代我们称之为“续行”的东西。参考链接https://pages.mtu.edu/~shene/COURSES/cs201/NOTES/chap01/continue.html。 - Denis Howe
11
没有回答问题。 - Peter VARGA
显示剩余6条评论

250

我曾经在一个小的Node.js项目中不得不这样做,找到了这个解决方法,将多行字符串存储为行数组,使其更易读(需要额外的代码将它们转换为字符串):

{
 "modify_head": [

  "<script type='text/javascript'>",
  "<!--",
  "  function drawSomeText(id) {",
  "  var pjs = Processing.getInstanceById(id);",
  "  var text = document.getElementById('inputtext').value;",
  "  pjs.drawText(text);}",
  "-->",
  "</script>"

 ],

 "modify_body": [

  "<input type='text' id='inputtext'></input>",
  "<button onclick=drawSomeText('ExampleCanvas')></button>"
 
 ],
}

一旦解析,我只需要使用myData.modify_head.join('\n')myData.modify_head.join(),具体取决于是否需要在每个字符串后面换行。

这看起来很整洁,但我必须在所有地方使用双引号。不过除此之外,我可以尝试使用YAML,但它有其他缺陷且不得到本地支持。


71
这是一个特定情境下的解决方案,不一定与问题相关。你所创建的不是多行字符串(无论如何也不可能),而是包含字符串的数组。 - Samuel Rivas
6
这展示了如何在字符串中插入换行符,但并未回答问题。这个答案回答了问题。 - fgrieu
1
fgrieu -- 也可以不添加换行符直接连接字符串。通过这个小改动,它确实提供了多行字符串的解决方法(只要您控制规定 JSON 模式)。我会尝试用这个来改进答案。 - drrob
2
谢谢,我喜欢这个。我会用它来处理我正在做的事情。看起来整洁有序。每个数组中的新行都将表示输出文本中的换行,虽然这种解决方案也适用于不插入换行符的情况。在我的JavaScript源代码中,我以前使用过这个解决方案,只是因为我喜欢它看起来有条理,而且不会让人怀疑最终字符串中有哪些空格。 - Gal
1
谢谢,这解决了我在VScode的launch.json中将命令行参数放在不同行的问题。 - Flux
显示剩余2条评论

145
检查规范!JSON语法的char生成可以采用以下值:
  • 任何Unicode字符,除"\或控制字符之外的字符
  • \"
  • \\
  • \/
  • \b
  • \f
  • \n
  • \r
  • \t
  • \u四个十六进制数字
换行符是“控制字符”,因此您不能在字符串中使用文字换行符。但是,您可以使用任何\n\r的组合进行编码。

现在它是ECMA-404)) http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf - gavenkoa
6
这是正确答案,因为它没有任何歧义。根据规范,允许使用新行,只需使用控制字符进行适当转义即可。 - Ryan
3
@AliKhaki 在 JSON 中不会实现所需的结果。要么你想到了其他事情(比如嵌入换行符),要么你在谈论某种编程语言中字符串字面量(包含 JSON)中的换行符,这又是另一回事。 - Lightness Races in Orbit
4
不对。这并不回答问题。问题不是如何将换行符放入字符串中,而是如何将一个字符串分布在多行上。正确的答案是:这是不可能的。 - Johannes Overmann

98

JSON 不支持为了可读性而换行。

最好的方法是使用一个能自动换行的集成开发环境(IDE)。


2
像BBEdit这样支持“软”换行的编辑器是理想的。它会将文本包装起来,使其全部出现在编辑器窗口的可见区域内,但只有您键入的行尾(例如,按回车键)在保存文件时才会保留。这使得更容易编辑具有非常长字符串的JSON,而无需诉诸于代码技巧或黑客。 - cshotton
20
有时我认为JSON格式设计得不够彻底。没有注释,也不支持多行。我知道它只是一种数据格式,但是“供人使用”。因此,加入一些“人性化”的功能会很有帮助。 - dvdmn
1
谢谢你的回答,让我感到开心。那其实是唯一正确的答案,因为JSON标准在这里非常严格,因此很难维护非常长的文本。为什么我自己没有想出这个简单的解决方案呢? :-) - Peter VARGA
@dvdmn 我完全同意。这就像是由一个90岁的程序员设计的,他最好的时光是在第一次登月之前。 - Peter VARGA
讽刺并不是最好的学习平台,尽管我也需要微笑一下。 - tangoal
1
无论 JSON 是否旨在可读性(如果是这样,我会同意有关其设计不佳的评论),事实是它是传输数据的绝佳格式(比 XML 更紧凑但仍易于专家阅读)。它不适合读取数据,对于编写配置来说尤其糟糕,因为上述限制。其中之一,YAML 就是专门为后者而设计的语言。 - user3758232

52

这是一个非常老的问题,但我在搜索时遇到了它,我想我知道你问题的源头。

JSON不允许在其数据中使用“真正的”换行符;它只能有转义后的换行符。参见@YOUanswer。根据问题,看起来你尝试用两种方式在Python中转义换行符:使用行续字符("\")或使用"\n"作为转义符。

但要记住:如果你在Python中使用字符串,特殊的转义字符("\t""\n")将被翻译成实际的控制字符!"\n"将被替换为表示换行符的ASCII控制字符,这恰好是JSON中不合法的字符。(至于行续字符,则只是去掉了换行符。)

所以您需要做的是防止Python转义字符。您可以通过使用原始字符串(在字符串前面加上r,例如r"abc\ndef"),或在换行符前面包含一个额外的斜杠("abc\\ndef")来实现这一点。
以上两种方法都不会将"\n"替换为真正的换行ASCII控制字符,而是将"\n"保留为两个字面字符,然后JSON可以解释为换行转义。

28
将属性值作为字符串数组编写。就像在这里提供的示例中一样https://gun.io/blog/multi-line-strings-in-json/。这将有所帮助。
我们可以始终使用字符串数组来表示多行字符串,例如以下内容。
{
    "singleLine": "Some singleline String",
    "multiline": ["Line one", "line Two", "Line Three"]
} 

我们可以轻松地迭代数组,以多行方式显示内容。


2
我建议您在回答中添加链接中的信息,因为链接可能会在未来失效。 - YoungHobbit
37
但是你有一个数组,不是一个字符串。数组和字符串是不同的。就是这样。 - 9ilsdx 9rvj 0lo
1
刚刚在想这个。很棒! - PhillipJacobs
1
当然,它会改变格式。但是,如果多行字符串的使用是为了在JSON文件开头添加一些文档目的的标题,那么它可以正常工作,并且人类可读性是最重要的方面。加上一些缩进后,它看起来更好。https://pastebin.com/Rs8HSQH5 - Eric Duminil
1
@BrandonStivers:通常情况下,您可以教机器学习新事物,因此他确实可以将格式指定为数组,并说每个数组条目都是一种新行。然后在程序中实现它。您的评论对于当前和特定用例确实是正确的,而提问者只是没有询问。无论如何,总的来说是一个好提示 - 那个提议的解决方案现在并不适用于所有情况。 - tangoal
显示剩余4条评论

5
这是一个很老的问题,但当我想要改进我们的 Vega JSON 规范代码的可读性时,我也有同样的问题,因为它使用了复杂的条件表达式。代码类似于这个
正如这个答案所说,JSON 不是为人类设计的。我理解这是一个历史性决定,并且在数据交换方面是有意义的。然而,在这种情况下,JSON 仍然被用作源代码。因此,我请求我们的工程师使用Hjson作为源代码并将其转换为 JSON。
例如,在 Git for Windows 环境中,您可以下载 Hjson cli 二进制文件并将其放置在 git/bin 目录中以供使用。然后,将 Hjson 源转换(转译)为 JSON。使用自动化工具(例如 Make)将有助于生成 JSON。
$ which hjson
/c/Program Files/git/bin/hjson

$ cat example.hjson
{
  md:
    '''
    First line.
    Second line.
      This line is indented by two spaces.
    '''
}

$ hjson -j example.hjson > example.json

$ cat example.json
{
  "md": "First line.\nSecond line.\n  This line is indented by two spaces."
}

如果在编程语言中使用转换后的JSON,那么像hjson-js这样的特定于语言的库会很有用。

我注意到相同的想法被发布在一个重复的问题中,但我想分享更多信息。


谢谢...需要这个。不确定我是否想要保存Hjson... 让软件来思考,而不是我的IDE,似乎更好。 - Joeri

3

虽然不标准,但我发现一些JSON库有支持多行字符串的选项。我必须提醒您,这会影响您的互操作性。

然而,在我遇到的特定情况中,我需要创建一个只被一个系统使用的配置文件,以便人类可以阅读和管理,并最终选择了此解决方案。

以下是在Java中使用 Jackson 实现此功能的方法:

JsonMapper mapper = JsonMapper.builder()
   .enable(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS)
   .build()

在Python中,您可以使用json.load的strict参数允许加载包含多行字符串的JSON:json.load(file_in, strict=False) - Anthony Hayward

2

假设问题与轻松编辑文本文件并手动将它们转换为json有关,我找到了两个解决方案:

  1. hjson(在this之前的回答中提到),您可以通过执行hjson source.json > target.hjson将现有的json文件转换为hjson格式,使用您喜欢的编辑器进行编辑,然后再将其转换回json hjson -j target.hjson > source.json。您可以在here下载二进制文件或使用在线转换here
  2. jsonnet也可以实现相同的功能,但格式略有不同(单引号和双引号字符串可以跨越多行)。方便的是,该网站主页具有可编辑的输入字段,因此您可以将多行json / jsonnet文件插入其中,它们将立即在线转换为标准json。请注意,jsonnet支持更多用于模板化json文件的好东西,因此根据您的需求,可能会很有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接