使用 JavaScript 打印漂亮的 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4810841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
pretty-print JSON using JavaScript
提问by Mark
How can I display JSON in an easy-to-read (for human readers) format? I'm looking primarily for indentation and whitespace, with perhaps even colors / font-styles / etc.
如何以易于阅读(供人类读者)的格式显示 JSON?我主要寻找缩进和空白,甚至可能有颜色/字体样式/等。
回答by user123444555621
Pretty-printing is implemented natively in JSON.stringify()
. The third argument enables pretty printing and sets the spacing to use:
漂亮打印在JSON.stringify()
. 第三个参数启用漂亮的打印并设置要使用的间距:
var str = JSON.stringify(obj, null, 2); // spacing level = 2
If you need syntax highlighting, you might use some regex magic like so:
如果你需要语法高亮,你可以像这样使用一些正则表达式:
function syntaxHighlight(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return json.replace(/("(\u[a-zA-Z0-9]{4}|\[^u]|[^\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
See in action here: jsfiddle
在此处查看操作:jsfiddle
Or a full snippet provided below:
或者下面提供的完整片段:
function output(inp) {
document.body.appendChild(document.createElement('pre')).innerHTML = inp;
}
function syntaxHighlight(json) {
json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
return json.replace(/("(\u[a-zA-Z0-9]{4}|\[^u]|[^\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
var obj = {a:1, 'b':'foo', c:[false,'false',null, 'null', {d:{e:1.3e5,f:'1.3e5'}}]};
var str = JSON.stringify(obj, undefined, 4);
output(str);
output(syntaxHighlight(str));
pre {outline: 1px solid #ccc; padding: 5px; margin: 5px; }
.string { color: green; }
.number { color: darkorange; }
.boolean { color: blue; }
.null { color: magenta; }
.key { color: red; }
回答by Rick Hanlon II
User Pumbaa80's answer is great if you have an objectyou want pretty printed. If you're starting from a valid JSON stringthat you want to pretty printed, you need to convert it to an object first:
如果您有想要漂亮打印的对象,则用户 Pumbaa80 的回答很棒。如果您从想要漂亮打印的有效 JSON字符串开始,则需要先将其转换为对象:
var jsonString = '{"some":"json"}';
var jsonPretty = JSON.stringify(JSON.parse(jsonString),null,2);
This builds a JSON object from the string, and then converts it back to a string using JSON stringify's pretty print.
这将从字符串构建一个 JSON 对象,然后使用 JSON stringify 的漂亮打印将其转换回字符串。
回答by Charmie
回答by Milen Boev
Based on Pumbaa80's answer I have modified the code to use the console.log colours (working on Chrome for sure) and not HTML. Output can be seen inside console. You can edit the _variables inside the function adding some more styling.
根据 Pumbaa80 的回答,我修改了代码以使用 console.log 颜色(肯定在 Chrome 上工作)而不是 HTML。输出可以在控制台内看到。您可以编辑函数内的 _variables 以添加更多样式。
function JSONstringify(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, '\t');
}
var
arr = [],
_string = 'color:green',
_number = 'color:darkorange',
_boolean = 'color:blue',
_null = 'color:magenta',
_key = 'color:red';
json = json.replace(/("(\u[a-zA-Z0-9]{4}|\[^u]|[^\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var style = _number;
if (/^"/.test(match)) {
if (/:$/.test(match)) {
style = _key;
} else {
style = _string;
}
} else if (/true|false/.test(match)) {
style = _boolean;
} else if (/null/.test(match)) {
style = _null;
}
arr.push(style);
arr.push('');
return '%c' + match + '%c';
});
arr.unshift(json);
console.log.apply(console, arr);
}
Here is a bookmarklet you can use:
这是您可以使用的书签:
javascript:function JSONstringify(json) {if (typeof json != 'string') {json = JSON.stringify(json, undefined, '\t');}var arr = [],_string = 'color:green',_number = 'color:darkorange',_boolean = 'color:blue',_null = 'color:magenta',_key = 'color:red';json = json.replace(/("(\u[a-zA-Z0-9]{4}|\[^u]|[^\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {var style = _number;if (/^"/.test(match)) {if (/:$/.test(match)) {style = _key;} else {style = _string;}} else if (/true|false/.test(match)) {style = _boolean;} else if (/null/.test(match)) {style = _null;}arr.push(style);arr.push('');return '%c' + match + '%c';});arr.unshift(json);console.log.apply(console, arr);};void(0);
Usage:
用法:
var obj = {a:1, 'b':'foo', c:[false,null, {d:{e:1.3e5}}]};
JSONstringify(obj);
Edit: I just tried to escape the % symbol with this line, after the variables declaration:
编辑:我只是试图在变量声明之后用这一行转义 % 符号:
json = json.replace(/%/g, '%%');
But I find out that Chrome is not supporting % escaping in the console. Strange... Maybe this will work in the future.
但我发现 Chrome 不支持控制台中的 % 转义。奇怪……也许这在未来会奏效。
Cheers!
干杯!
回答by Adel MANI
var jsonObj = {"streetLabel": "Avenue Anatole France", "city": "Paris 07", "postalCode": "75007", "countryCode": "FRA", "countryLabel": "France" };
document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj);
In case of displaying in HTML, you should to add a balise <pre></pre>
在 HTML 中显示的情况下,您应该添加一个 balise <pre></pre>
document.getElementById("result-after").innerHTML = "<pre>"+JSON.stringify(jsonObj,undefined, 2) +"</pre>"
Example:
例子:
var jsonObj = {"streetLabel": "Avenue Anatole France", "city": "Paris 07", "postalCode": "75007", "countryCode": "FRA", "countryLabel": "France" };
document.getElementById("result-before").innerHTML = JSON.stringify(jsonObj);
document.getElementById("result-after").innerHTML = "<pre>"+JSON.stringify(jsonObj,undefined, 2) +"</pre>"
div { float:left; clear:both; margin: 1em 0; }
<div id="result-before"></div>
<div id="result-after"></div>
回答by mythz
I use the JSONView Chrome extension(it is as pretty as it gets :):
我使用JSONView Chrome 扩展程序(它非常漂亮:):
Edit: added jsonreport.js
编辑:添加 jsonreport.js
I've also released an online stand-alone JSON pretty print viewer, jsonreport.js, that provides a human readable HTML5 report you can use to view any JSON data.
我还发布了一个在线独立 JSON 漂亮打印查看器 jsonreport.js,它提供了一个人类可读的 HTML5 报告,您可以使用它来查看任何 JSON 数据。
You can read more about the format in New JavaScript HTML5 Report Format.
您可以在New JavaScript HTML5 Report Format 中阅读有关该格式的更多信息。
回答by adius
You can use console.dir()
, which is a shortcut for console.log(util.inspect())
.
(The only difference is that it bypasses any custom inspect()
function defined on an object.)
您可以使用console.dir()
,这是 的快捷方式console.log(util.inspect())
。(唯一的区别是它绕过了inspect()
在对象上定义的任何自定义函数。)
It uses syntax-highlighting, smart indentation, removes quotes from keysand just makes the output as pretty as it gets.
它使用语法高亮、智能缩进、从键中删除引号并使输出尽可能漂亮。
const object = JSON.parse(jsonString)
console.dir(object, {depth: null, colors: true})
and for the command line:
对于命令行:
cat package.json | node -e "process.stdin.pipe(new stream.Writable({write: chunk => console.dir(JSON.parse(chunk), {depth: null, colors: true})}))"
cat package.json | node -e "process.stdin.pipe(new stream.Writable({write: chunk => console.dir(JSON.parse(chunk), {depth: null, colors: true})}))"
回答by James Heazlewood
Here's user123444555621's awesome HTML one adapted for terminals. Handy for debugging Node scripts:
这是 user123444555621 的很棒的 HTML 一个适用于终端。方便调试 Node 脚本:
function prettyJ(json) {
if (typeof json !== 'string') {
json = JSON.stringify(json, undefined, 2);
}
return json.replace(/("(\u[a-zA-Z0-9]{4}|\[^u]|[^\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
function (match) {
let cls = "\x1b[36m";
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = "\x1b[34m";
} else {
cls = "\x1b[32m";
}
} else if (/true|false/.test(match)) {
cls = "\x1b[35m";
} else if (/null/.test(match)) {
cls = "\x1b[31m";
}
return cls + match + "\x1b[0m";
}
);
}
Usage:
用法:
// thing = any json OR string of json
prettyJ(thing);
回答by Phrogz
Unsatisfied with other pretty printers for Ruby, I wrote my own (NeatJSON) and then ported it to JavaScriptincluding a free online formatter. The code is free under MIT license (quite permissive).
对 Ruby 的其他漂亮打印机不满意,我自己编写了 ( NeatJSON),然后将它移植到 JavaScript,包括一个免费的在线格式化程序。该代码在 MIT 许可下是免费的(非常宽松)。
Features (all optional):
功能(所有可选):
- Set a line width and wrap in a way that keeps objects and arrays on the same line when they fit, wrapping one value per line when they don't.
- Sort object keys if you like.
- Align object keys (line up the colons).
- Format floating point numbers to specific number of decimals, without messing up the integers.
- 'Short' wrapping mode puts opening and closing brackets/braces on the same line as values, providing a format that some prefer.
- Granular control over spacing for arrays and objects, between brackets, before/after colons and commas.
- Function is made available to both web browsers and Node.js.
- 设置线宽并以一种方式换行,当对象和数组适合时将它们保持在同一行上,当它们不适合时每行换行一个值。
- 如果您愿意,可以对对象键进行排序。
- 对齐对象键(对齐冒号)。
- 将浮点数格式化为特定的小数位数,而不会弄乱整数。
- 'Short' 换行模式将左括号和右括号/大括号与值放在同一行,提供了一些人喜欢的格式。
- 对数组和对象、方括号之间、冒号和逗号之前/之后的间距进行精细控制。
- 函数可用于 Web 浏览器和 Node.js。
I'll copy the source code here so that this is not just a link to a library, but I encourage you to go to the GitHub project page, as that will be kept up-to-date and the code below will not.
我将在此处复制源代码,以便这不仅仅是指向库的链接,但我鼓励您转到GitHub 项目页面,因为它会保持最新状态,而下面的代码不会。
(function(exports){
exports.neatJSON = neatJSON;
function neatJSON(value,opts){
opts = opts || {}
if (!('wrap' in opts)) opts.wrap = 80;
if (opts.wrap==true) opts.wrap = -1;
if (!('indent' in opts)) opts.indent = ' ';
if (!('arrayPadding' in opts)) opts.arrayPadding = ('padding' in opts) ? opts.padding : 0;
if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0;
if (!('afterComma' in opts)) opts.afterComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
if (!('beforeComma' in opts)) opts.beforeComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
if (!('afterColon' in opts)) opts.afterColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
if (!('beforeColon' in opts)) opts.beforeColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
var apad = repeat(' ',opts.arrayPadding),
opad = repeat(' ',opts.objectPadding),
comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma),
colon = repeat(' ',opts.beforeColon)+':'+repeat(' ',opts.afterColon);
return build(value,'');
function build(o,indent){
if (o===null || o===undefined) return indent+'null';
else{
switch(o.constructor){
case Number:
var isFloat = (o === +o && o !== (o|0));
return indent + ((isFloat && ('decimals' in opts)) ? o.toFixed(opts.decimals) : (o+''));
case Array:
var pieces = o.map(function(v){ return build(v,'') });
var oneLine = indent+'['+apad+pieces.join(comma)+apad+']';
if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine;
if (opts.short){
var indent2 = indent+' '+apad;
pieces = o.map(function(v){ return build(v,indent2) });
pieces[0] = pieces[0].replace(indent2,indent+'['+apad);
pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']';
return pieces.join(',\n');
}else{
var indent2 = indent+opts.indent;
return indent+'[\n'+o.map(function(v){ return build(v,indent2) }).join(',\n')+'\n'+indent+']';
}
case Object:
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [JSON.stringify(k), build(o[k],'')];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
keyvals = keyvals.map(function(kv){ return kv.join(colon) }).join(comma);
var oneLine = indent+"{"+opad+keyvals+opad+"}";
if (opts.wrap===false || oneLine.length<opts.wrap) return oneLine;
if (opts.short){
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [indent+' '+opad+JSON.stringify(k),o[k]];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'{');
if (opts.aligned){
var longest = 0;
for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
var padding = repeat(' ',longest);
for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
}
for (var i=keyvals.length;i--;){
var k=keyvals[i][0], v=keyvals[i][1];
var indent2 = repeat(' ',(k+colon).length);
var oneLine = k+colon+build(v,'');
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
}
return keyvals.join(',\n') + opad + '}';
}else{
var keyvals=[],i=0;
for (var k in o) keyvals[i++] = [indent+opts.indent+JSON.stringify(k),o[k]];
if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
if (opts.aligned){
var longest = 0;
for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
var padding = repeat(' ',longest);
for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
}
var indent2 = indent+opts.indent;
for (var i=keyvals.length;i--;){
var k=keyvals[i][0], v=keyvals[i][1];
var oneLine = k+colon+build(v,'');
keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
}
return indent+'{\n'+keyvals.join(',\n')+'\n'+indent+'}'
}
default:
return indent+JSON.stringify(o);
}
}
}
function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
var result = '';
while(true){
if (times & 1) result += str;
times >>= 1;
if (times) str += str;
else break;
}
return result;
}
function padRight(pad, str){
return (str + pad).substring(0, pad.length);
}
}
neatJSON.version = "0.5";
})(typeof exports === 'undefined' ? this : exports);
回答by gavenkoa
For debugging purpose I use:
出于调试目的,我使用:
console.debug("%o", data);