可以在JSON对象中使用尾随逗号吗?

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

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

给你一个字符串

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

这是允许的吗?

154984 次浏览

不。JSON规范,维护在http://json.org,不允许尾随逗号。据我所知,一些解析器在读取JSON字符串时可能会默默地允许它们,而其他解析器则会抛出错误。对于互操作性,不应该包含它。

上面的代码可以重新构造,可以在添加数组结束符时删除后面的逗号,也可以在项之前添加逗号,对第一个项跳过逗号。

不幸的是,JSON规范不允许后面有逗号。有一些浏览器允许这样做,但通常需要考虑所有浏览器。

一般来说,我试图把问题转过来,在实际值之前添加逗号,所以你最终得到的代码看起来像这样:

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时,我使用的另一种替代方法是始终在每个条目后面附加一个逗号(正如您上面所做的那样),然后在末尾添加一个没有逗号的虚拟条目(但这只是懒惰;->)。

不幸的是,它不能很好地使用数组。

有趣的是,C &c++(我想c#也一样,但我不确定)特别允许在后面加逗号——原因正是:它使以编程方式生成列表更加容易。不知道为什么JavaScript没有效仿他们。

PHP程序员可能想要查看内爆()。它接受一个数组,使用字符串将其连接起来。

文档

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

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

也许不是最好的方法,但比每次检查它是否是循环中的最后一个对象要便宜一些。

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

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

同样,如果您使用的是PHP 5.2.0或更高版本,则可以使用内置的JSON API格式化响应。

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

Firefox和Chrome都处理得很好。但是IE(所有版本)似乎都坏了。我的意思是真正的中断,停止阅读剩余的剧本。

记住这一点,并且考虑到编写兼容的代码总是很好的事实,我建议花费额外的精力确保没有尾随逗号。

:)

简单,便宜,易于阅读,并且无论规格如何都能正常工作。

$delimiter = '';
for ....  {
print $delimiter.$whatever
$delimiter = ',';
}
$delim的冗余赋值代价很小。 如果没有显式的循环,但有单独的代码片段,也同样有效

尾随逗号在JavaScript中是允许的,但在IE中不允许。Douglas Crockford的无版本JSON规范不允许它们,因为它是无版本的,所以不应该改变。ES5 JSON规范允许它们作为扩展,但Crockford的RFC 4627不允许,ES5恢复为不允许。火狐紧随其后。ie就是我们不能拥有美好事物的原因。

如前所述,JSON规范(基于ECMAScript 3)不允许尾随逗号。ES >= 5允许,所以你可以在纯JS中使用这个符号。这是有争议的,一些解析器做了支持它(http://bolinfest.com/essays/json.htmlhttp://whereswalden.com/2010/09/08/spidermonkey-json-change-trailing-commas-no-longer-accepted/),但它的规范事实(如http://json.org/所示),它不应该在JSON中工作。那东西说……

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

例如(在c风格的伪代码中,类似于OP的建议代码):

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("]");

使用JSON5。不要使用JSON。

  • 对象和数组可以以逗号结尾
  • 如果对象键是有效的标识符,则可以不加引号
  • 字符串可以使用单引号
  • 字符串可以被分割成多行
  • 数字可以是十六进制(以16为基数)
  • 数字可以以小数点(前导或后导)开始或结束。
  • 数字可以包括∞和-∞。
  • 数字可以以显式的加号(+)开头。
  • 内联(单行)和块(多行)注释都是允许的。

< a href = " http://json5.org/ " rel = " noreferrer > http://json5.org/ < / >

https://github.com/aseemk/json5

根据类JSONArray规范:

  • 一个额外的,(逗号)可以出现在右括号之前。
  • 空值将被插入,(逗号)省略。

所以,根据我的理解,应该允许这样写:

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

但是有些解析器可能会返回7作为项目计数(如Daniel Earwicker指出的IE8),而不是预期的6。


编辑:

我发现这个JSON验证器根据RFC 4627 (JavaScript对象符号的应用程序/ JSON媒体类型)和JavaScript语言规范验证JSON字符串。实际上,这里带逗号的数组只对JavaScript有效,而对RFC 4627规范无效。

然而,在RFC 4627规范中指出:

2.3. 数组

数组结构用0周围的方括号表示 或更多的值(或元素)。元素之间用逗号分隔

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

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

P.S. RFC 4627不是一个标准(如明确声明的那样),并且已经被RFC 7159(这是一个提议的标准)RFC 7159淘汰

不建议这样做,但您仍然可以执行类似这样的操作来解析它。

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

使用relax JSON,你可以有后面的逗号,或者省略逗号。它们是可选的。

在解析类似json的文档时,完全没有必要使用逗号。

看一看relax JSON规范,你会发现原始JSON规范是多么“嘈杂”。太多的逗号和引号……

http://www.relaxedjson.org

您还可以使用这个在线RJSON解析器尝试您的示例,并查看它是否被正确解析。

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

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

s.append("[ "); // there is a space after the left bracket
for (i = 0; i < 5; ++i) {
s.appendF("\"%d\",", i); // always add comma
}
s.back() = ']'; // modify last comma (or the space) to right bracket

由于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

如上所述,这是不允许的。但在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)

不。“铁路图”;在https://json.org中是对规范的精确翻译,并明确指出,总是出现在value之前,而不是直接出现在]之前:

 array的铁路图

}:

rail diagram for object .

我不会参加辩论俱乐部,我会坚持Defensive Programming的原则,将两种简单的技巧结合起来,以简化与他人的接口:

  • 作为一个开发了接收 json数据的应用程序的开发者,我将是放松允许,后面是逗号。

  • 当开发一个 json的应用程序时,我将是严格的,并使用其他答案的聪明技术之一,只在项目之间添加逗号和避免后面的逗号。

还有更大的问题需要解决……

String l = "[" + List<int>.generate(5, (i) => i + 1).join(",") + "]";

json不允许使用尾随逗号。我喜欢的一个解决方案是,如果不是为外部收件人而是为自己的项目编写,那么可以在将接收端上的尾随逗号提供给json解析器之前删除(或用空格替换)。我对最外层json对象中的尾随逗号这样做。方便的是,如果你在后面加一个对象,你就不需要在倒数第二个对象上加逗号了。如果你的配置文件在版本控制系统中,这也会使差异更清晰,因为它只会显示你实际添加的内容。

    char* str = readFile("myConfig.json");
char* chr = strrchr(str, '}') - 1;
int i = 0;
while( chr[i] == ' ' || chr[i] == '\n' ){
i--;
}
if( chr[i] == ',' ) chr[i] = ' ';
JsonParser parser;
parser.parse(str);