我使用的服务使用了不正确的 JSON 格式(属性周围没有双引号)。所以我需要发送
{ name: "John Smith" }
代替 { "name": "John Smith" }
由于这不是我的服务,因此无法更改此格式。
任何人都知道字符串化路由来格式化上面的 JavaScript 对象?
我使用的服务使用了不正确的 JSON 格式(属性周围没有双引号)。所以我需要发送
{ name: "John Smith" }
代替 { "name": "John Smith" }
由于这不是我的服务,因此无法更改此格式。
任何人都知道字符串化路由来格式化上面的 JavaScript 对象?
在大多数情况下,这个简单的正则表达式解决方案适用于取消引用 JSON 属性名称:
const object = { name: 'John Smith' };
const json = JSON.stringify(object); // {"name":"John Smith"}
console.log(json);
const unquoted = json.replace(/"([^"]+)":/g, '$1:');
console.log(unquoted); // {name:"John Smith"}
极端情况:
var json = '{ "name": "J\\":ohn Smith" }'
json.replace(/\\"/g,"\uFFFF"); // U+ FFFF
json = json.replace(/"([^"]+)":/g, '$1:').replace(/\uFFFF/g, '\\\"');
// '{ name: "J\":ohn Smith" }'
特别感谢 Rob W 修复它。
在正常情况下,上述正则表达式会起作用,但从数学上讲,用正则表达式描述 JSON 格式是不可能的,这样它就可以在每种情况下都起作用(用正则表达式计算相同数量的大括号是不可能的。)因此,我有创建一个新函数,通过原生函数正式解析 JSON 字符串并重新序列化它来删除引号:
function stringify(obj_from_json) {
if (typeof obj_from_json !== "object" || Array.isArray(obj_from_json)){
// not an object, stringify using native function
return JSON.stringify(obj_from_json);
}
// Implements recursive object serialization according to JSON spec
// but without quotes around the keys.
let props = Object
.keys(obj_from_json)
.map(key => `${key}:${stringify(obj_from_json[key])}`)
.join(",");
return `{${props}}`;
}
看起来这是您正在寻找的一个简单的 Object toString 方法。
在 Node.js 中,这是通过使用 util 对象并调用 util.inspect(yourObject) 来解决的。这会给你你想要的一切。点击此链接以获取更多选项,包括方法应用的深度。http://nodejs.org/api/util.html#util_util_inspect_object_options
所以,你要找的基本上是一个对象检查器,而不是一个 JSON 转换器。JSON 格式指定所有属性都必须用双引号括起来。因此不会有 JSON 转换器来执行您想要的操作,因为这根本不是 JSON 格式。此处的规范:https : //developer.mozilla.org/en-US/docs/Using_native_JSON
根据您的服务器的语言,您需要对象到字符串或检查。
有一个警告,下面是关于浏览器中的后视支持,这里是:
function cleanIt(obj) {
var cleaned = JSON.stringify(obj, null, 2);
return cleaned.replace(/^[\t ]*"[^:\n\r]+(?<!\\)":/gm, function (match) {
return match.replace(/"/g, "");
});
}
注意: IE 或奇怪的是,截至 2021 年 6 月 18 日的任何版本的 Safari都不支持 Lookbehinds 。要在那里使用,请
(?<!\\)
从正则表达式中删除并注意下面提到的“陷阱”条件。
用漂亮的字符串化,使用我们的正则表达式来查找键,然后通过替换器函数替换每个键匹配,该函数说“这是删除所有双引号的匹配”。由于我们只将键匹配到它们的冒号,这正是我们想要的。
详细说明如下。
不幸的是,正如Adel 指出的那样,Derek 的无正则表达式解决方案存在一个非常严重的问题。它不处理对象数组。你看到它是如何短路并说,“如果它是一个数组,让我们JSON.stringify
处理它”?这适用于简单的值类型,但不适用于对象。
// \/\/\/ OH NOES!!! \/\/\/
if (typeof obj_from_json !== "object" || Array.isArray(obj_from_json)){
// not an object, stringify using native function
return JSON.stringify(obj_from_json);
// ^^^^^^^^^^^^^^ No! Don't do that!
}
var obj = {
name: "John Smith",
favoriteObjects: [
{ b: "there's", c: "always", d: "something" },
[1, 2, "spam", { f: "hello" }],
{ vowels: "are missing" },
],
favoriteFruits: ["Apple", "Banana"],
};
这是空白输出:
{
name:"John Smith",
favoriteObjects:[
{
"b":"there's", <<< Major
"c":"always", <<< fails
"d":"something" <<< here
},
[
1,2,"spam",
{
"f":"hello" <<< and here.
}
],
{
"vowels":"are missing" <<< again.
}
],
favoriteFruits:["Apple","Banana"] <<< that worked!
}
看?尽管字符串数组 ( favoriteFruits
) 有效,但我们仍然在数组中的对象(如favoriteObjects
)的第二级序列化中获得了引号。坏的。
我花了太多时间试图清理该函数,然后才想出一个巧妙的技巧来大大降低问题的复杂性,我认为这将正则表达式带回了混合中。
stringify
用空格在McGuire 先生的脉络中,我只想对您说一句话,就一句话:
空白。
让我们JSON.stringify
留一些空白。这使得正则表达式从键中删除引号更容易。
用这个开始你的解决方案:
var cleaned = JSON.stringify(x, null, 2);
调用stringify
说“字符串化x
(第一个参数),没有花哨的替换函数(由 的第二个参数表示null
)2
,对于序列化中的每个深度级别,都有两个(第三个参数)空格的空格。” 这2
也让我们为每个房产购买了单独的产品线。
{
"name": "John Smith",
"favoriteObjects": [
{
"b": "there's",
"c": "always",
// etc...
每个键现在都很好地位于一行的开头。那我们可以处理。
让我们创建一个查找键的正则表达式,并且只查找键,然后将其周围的"
. 因为我们知道,钥匙都对自己行了,事情多简单。
唯一真正的问题是属性的值是否包含":
中途。那会把事情搞砸。
"a": [
"This could \": be bad",
"QQ"
]
我想通过对旧浏览器的花哨的负面前瞻来解决这个问题,但放弃并使用了负面的后视。Negative lookbehind 仅在 2018 年之后被部分浏览器支持(这里 2ality 的lookbehind 提案历史描述,浏览器兼容性可以在这里找到)。
/^[\t ]*"[^:\n\r]+(?<!\\)":/gm
那个正则...
/
^[\t ]*
"
"
:
或一个换行符
[^:\n\r]+
":
(否定后向警告)前面没有反斜杠
(?<!\\)":
/gm
结果:
{
name: "John Smith",
favoriteObjects: [
{
b: "there's",
c: "always",
d: "something"
},
[
1,
2,
"spam",
{
f: "hello"
}
],
{
vowels: "are missing"
}
],
favoriteFruits: [
"Apple",
"Banana"
]
}
在贾登特提出要求后的短短八年半时间里,QED 提出了要求。现在就是服务!
快速更新:一个更好的答案,如果你不一定需要在代码中发生这种情况(尽管在某些用例中,你也可以直接调用这个库),可以使用prettier,它可以很好地清理事物。
您可以查看由定义 JSON 格式的人创建的解析器的源代码。寻找函数调用:这些函数用引号包围一个值。键在第326和338行引用。json2.js
quote
修改后不要包含库。而是只取相关的 ( stringify
) 部分,或者至少JSON
用其他东西替换,例如。FAKEJSON
.
例如,FAKEJSON
只定义了一个对象stringify
:http : //jsfiddle.net/PYudw/
找到了一个很好的 NPM 包来做到这一点:
https://www.npmjs.com/package/stringify-object
const stringify = require('stringify-object')
let prettyOutput = stringify(json);
效果很好。