你能在JSON对象中使用尾随逗号吗?

时间:2008-10-14 16:02:16

标签: json syntax delimiter

当手动生成JSON对象或数组时,通常更容易在对象或数组中的最后一项上留下尾随逗号。例如,从字符串数组输出的代码可能看起来像(在像C ++一样的伪代码中):

s.append("[");
for (i = 0; i < 5; ++i) {
    s.appendF("\"%d\",", i);
}
s.append("]");

给你一个像

这样的字符串
[0,1,2,3,4,5,]

这是允许的吗?

19 个答案:

答案 0 :(得分:214)

不幸的是the JSON specification不允许使用尾随逗号。有一些浏览器允许它,但通常你需要担心所有的浏览器。

一般情况下,我尝试解决问题,并在实际值之前添加逗号,因此您最终得到的代码如下所示:

s.append("[");
for (i = 0; i < 5; ++i) {
  if (i) s.append(","); // add the comma only if this isn't the first entry
  s.appendF("\"%d\"", i);
}
s.append("]");

for循环中额外的一行代码并不昂贵......

我在从某个表单的字典中输出结构到JSON时使用的另一个替代方法是在每个条目之后总是附加一个逗号(如上所述),然后在结尾处添加一个没有尾随的虚拟条目逗号(但这只是懒惰; - &gt;)。

不幸的是,对阵列不能正常工作。

答案 1 :(得分:123)

没有。保持在http://json.org的JSON规范不允许使用尾随逗号。从我所看到的,一些解析器可能在读取JSON字符串时默默地允许它们,而其他解析器会抛出错误。对于互操作性,不应包含它。

上面的代码可以重新构建,在添加数组终结符时删除尾随的逗号,或者在项目之前添加逗号,跳过第一个代码。

答案 2 :(得分:98)

简单,便宜,易于阅读,无论规格如何,它始终有效。

$delimiter = '';
for ....  {
    print $delimiter.$whatever
    $delimiter = ',';
}

$ delim的冗余分配是一个非常小的代价。 如果没有显式循环但是单独的代码片段,也可以正常工作。

答案 3 :(得分:19)

JavaScript中允许使用尾随逗号,但在IE中不起作用。道格拉斯克罗克福德的无版本JSON规范不允许它们,因为它是无版本的,所以不应该改变。 ES5 JSON规范允许它们作为扩展,但Crockford的RFC 4627没有,并且ES5恢复禁止它们。 Firefox紧随其后。 Internet Explorer是我们不能拥有好东西的原因。

答案 4 :(得分:13)

正如已经说过的那样,JSON规范(基于ECMAScript 3)不允许使用尾随逗号。 ES&gt; = 5允许它,因此您可以在纯JS中实际使用该表示法。它已被争论,并且一些解析器 支持它(http://bolinfest.com/essays/json.htmlhttp://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/),但它是规范事实(如{ {3}})它不应该在JSON中工作。那件事说......

...我想知道为什么没有人指出你实际上可以在第0次迭代时拆分循环并使用前导逗号而不是尾随一个来摆脱比较代码气味和循环中的任何实际性能开销,导致代码实际上比其他提出的解决方案更短,更简单,更快(由于循环中没有分支/条件)。

E.g。 (采用与OP提议的代码类似的C风格伪代码):

s.append("[");
// MAX == 5 here. if it's constant, you can inline it below and get rid of the comparison
if ( MAX > 0 ) {
    s.appendF("\"%d\"", 0); // 0-th iteration
    for( int i = 1; i < MAX; ++i ) {
        s.appendF(",\"%d\"", i); // i-th iteration
    }
}
s.append("]");

答案 5 :(得分:12)

PHP编码员可能想要查看 implode()。这需要一个数组使用字符串连接起来。

来自docs ...

$array = array('lastname', 'email', 'phone');
echo implode(",", $array); // lastname,email,phone

答案 6 :(得分:7)

有趣的是,C&amp; C ++(我认为C#,但我不确定)专门允许尾随逗号 - 正是由于给出的原因:它使程序化生成列表变得更加容易。不确定为什么JavaScript没有跟随他们的领先优势。

答案 7 :(得分:4)

使用JSON5。不要使用JSON。

  • 对象和数组可以包含尾随逗号
  • 如果对象密钥是有效标识符
  • ,则可以不加引号
  • 字符串可以单引号
  • 字符串可以分为多行
  • 数字可以是十六进制(基数为16)
  • 数字可以以(前导或尾随)小数点开头或结尾。
  • 数字可以包括Infinity和-Infinity。
  • 数字可以以明确的加号(+)开头。
  • 允许内联(单行)和阻止(多行)注释。

http://json5.org/

https://github.com/aseemk/json5

答案 8 :(得分:2)

根据Class JSONArray specification

  • 额外的(逗号)可能会出现在结束括号之前。
  • 当有(逗号)省略时,将插入空值。

所以,据我所知,应该允许写:

[0,1,2,3,4,5,]

但是可能会发生一些解析器将7作为项目计数(如Daniel Earwicker指出的IE8)而不是预期的6。

编辑:

我发现这个JSON Validator验证了针对RFC 4627(JavaScript Object Notation的应用程序/ json媒体类型)和JavaScript语言规范的JSON字符串。实际上,这里一个带有尾随逗号的数组被认为仅适用于JavaScript而不适用于RFC 4627规范。

然而,在RFC 4627规范中声明:

  

2.3。阵列

     

数组结构表示为零的方括号   或更多值(或元素)。元素以逗号分隔。

array = begin-array [ value *( value-separator value ) ] end-array

对我而言,这又是一个解释问题。如果你写元素用逗号分隔(没有说明特殊情况,比如最后一个元素),可以用两种方式理解它。

P.S。 RFC 4627不是标准(如明确说明的那样),并且已经被RFC 7159(提议的标准)所限制RFC 7159

答案 9 :(得分:1)

我保留当前计数并将其与总计数进行比较。如果当前计数小于总计数,则显示逗号。

如果在执行JSON生成之前没有总计数,则可能无效。

然后,如果你使用PHP 5.2.0或更高版本,你可以使用内置的JSON API格式化你的响应。

答案 10 :(得分:1)

根据我过去的经验,我发现不同的浏览器以不同的方式处理JSON中的尾随逗号。

Firefox和Chrome都处理得很好。但IE(所有版本)似乎打破了。我的意思是真的打破并停止阅读剧本的其余部分。

牢记这一点,以及编写兼容代码总是很好的事实,我建议花费额外的努力来确保没有尾随逗号。

:)

答案 11 :(得分:1)

使用Relaxed JSON,您可以使用逗号,或只留下逗号。它们是可选的。

没有理由需要存在逗号来解析类似JSON的文档。

看一下轻松的JSON规范,你会看到嘈杂的&#39;原始的JSON规范是。太多的逗号和引号...

http://www.relaxedjson.org

您也可以使用此在线RJSON解析器试用您的示例,并看到它被正确解析。

http://www.relaxedjson.org/docs/converter.html?source=%5B0%2C1%2C2%2C3%2C4%2C5%2C%5D

答案 12 :(得分:1)

不。 https://json.org中的“铁路图”是规范的精确翻译,并清楚表明,总是在value之前,而不是在]之前:

railroad diagram for array

}

railroad diagram for object

答案 13 :(得分:0)

我通常遍历数组并在字符串中的每个条目后附加逗号。在循环之后,我再次删除最后一个逗号。

也许不是最好的方法,但是比每次检查更便宜,如果它是循环中的最后一个对象我猜。

答案 14 :(得分:0)

不推荐,但您仍然可以执行此类操作来解析它。

jsonStr = '[0,1,2,3,4,5,]';
let data;
eval('data = ' + jsonStr);
console.log(data)

答案 15 :(得分:0)

有一种方法可以避免循环中的if分支。

$this

答案 16 :(得分:0)

由于使用了for循环对数组或类似的可迭代数据结构进行迭代,因此我们可以使用所示的数组长度,

awk -v header="FirstName,LastName,DOB" '
  BEGIN {
    FS = ",";
    print("[");
    columns = split(header, column_names, ",");
  }
  { print("  {");
    for (i = 1; i < columns; i++) {
      printf("    \"%s\":\"%s\",\n", column_names[i], $(i));
    }
    printf("    \"%s\":\"%s\"\n", column_names[i], $(i));
    print("  }");
  }
  END { print("]"); } ' datafile.txt

包含datafile.txt的

 Angela,Baker,2010-05-23
 Betty,Crockett,1990-12-07
 David,Done,2003-10-31

答案 17 :(得分:0)

如上所述,这是不允许的。但是在JavaScript中,这是:

var a = Array()
for(let i=1; i<=5; i++) {
    a.push(i)
}
var s = "[" + a.join(",") + "]"

(在Firefox,Chrome,Edge,IE11中正常工作,而在IE9、8、7、5中不使用let

答案 18 :(得分:0)

我不会参加辩论俱乐部,而是申请Defensive Programming。作为接收JSON数据的应用程序的开发人员,我允许使用逗号结尾。在开发写json的应用程序时,我将使用其他答案中的一种巧妙技巧,仅在项目之间添加逗号。还有更大的问题需要解决...