pretty-print JSON using JavaScript

后端 未结 24 1669
一向
一向 2020-11-21 06:45

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.

相关标签:
24条回答
  • 2020-11-21 07:08
    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>

    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>

    0 讨论(0)
  • 2020-11-21 07:11

    Pretty-printing is implemented natively in JSON.stringify(). The third argument enables pretty printing and sets the spacing to use:

    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, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
        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

    Or a full snippet provided below:

    function output(inp) {
        document.body.appendChild(document.createElement('pre')).innerHTML = inp;
    }
    
    function syntaxHighlight(json) {
        json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
        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; }

    0 讨论(0)
  • 2020-11-21 07:11

    Here's user123444555621's awesome HTML one adapted for terminals. Handy for debugging Node scripts:

    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);
    
    0 讨论(0)
  • 2020-11-21 07:14

    User Pumbaa80's answer is great if you have an object you want pretty printed. If you're starting from a valid JSON string that you want to pretty printed, you need to convert it to an object first:

    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.

    0 讨论(0)
  • 2020-11-21 07:14

    Thanks a lot @all! Based on the previous answers, here is another variant method providing custom replacement rules as parameter:

     renderJSON : function(json, rr, code, pre){
       if (typeof json !== 'string') {
          json = JSON.stringify(json, undefined, '\t');
       }
      var rules = {
       def : 'color:black;',    
       defKey : function(match){
                 return '<strong>' + match + '</strong>';
              },
       types : [
           {
              name : 'True',
              regex : /true/,
              type : 'boolean',
              style : 'color:lightgreen;'
           },
    
           {
              name : 'False',
              regex : /false/,
              type : 'boolean',
              style : 'color:lightred;'
           },
    
           {
              name : 'Unicode',
              regex : /"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?/,
              type : 'string',
              style : 'color:green;'
           },
    
           {
              name : 'Null',
              regex : /null/,
              type : 'nil',
              style : 'color:magenta;'
           },
    
           {
              name : 'Number',
              regex : /-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/,
              type : 'number',
              style : 'color:darkorange;'
           },
    
           {
              name : 'Whitespace',
              regex : /\s+/,
              type : 'whitespace',
              style : function(match){
                 return '&nbsp';
              }
           } 
    
        ],
    
        keys : [
           {
               name : 'Testkey',
               regex : /("testkey")/,
               type : 'key',
               style : function(match){
                 return '<h1>' + match + '</h1>';
              }
           }
        ],
    
        punctuation : {
              name : 'Punctuation',
              regex : /([\,\.\}\{\[\]])/,
              type : 'punctuation',
              style : function(match){
                 return '<p>________</p>';
              }
           }
    
      };
    
      if('undefined' !== typeof jQuery){
         rules = $.extend(rules, ('object' === typeof rr) ? rr : {});  
      }else{
         for(var k in rr ){
            rules[k] = rr[k];
         }
      }
        var str = json.replace(/([\,\.\}\{\[\]]|"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
        var i = 0, p;
        if (rules.punctuation.regex.test(match)) {
                   if('string' === typeof rules.punctuation.style){
                       return '<span style="'+ rules.punctuation.style + '">' + match + '</span>';
                   }else if('function' === typeof rules.punctuation.style){
                       return rules.punctuation.style(match);
                   } else{
                      return match;
                   }            
        }
    
        if (/^"/.test(match)) {
            if (/:$/.test(match)) {
                for(i=0;i<rules.keys.length;i++){
                p = rules.keys[i];
                if (p.regex.test(match)) {
                   if('string' === typeof p.style){
                       return '<span style="'+ p.style + '">' + match + '</span>';
                   }else if('function' === typeof p.style){
                       return p.style(match);
                   } else{
                      return match;
                   }                
                 }              
               }   
                return ('function'===typeof rules.defKey) ? rules.defKey(match) : '<span style="'+ rules.defKey + '">' + match + '</span>';            
            } else {
                return ('function'===typeof rules.def) ? rules.def(match) : '<span style="'+ rules.def + '">' + match + '</span>';
            }
        } else {
            for(i=0;i<rules.types.length;i++){
             p = rules.types[i];
             if (p.regex.test(match)) {
                   if('string' === typeof p.style){
                       return '<span style="'+ p.style + '">' + match + '</span>';
                   }else if('function' === typeof p.style){
                       return p.style(match);
                   } else{
                      return match;
                   }                
              }             
            }
    
         }
    
        });
    
      if(true === pre)str = '<pre>' + str + '</pre>';
      if(true === code)str = '<code>' + str + '</code>';
      return str;
     }
    
    0 讨论(0)
  • 2020-11-21 07:15

    If you need this to work in a textarea the accepted solution will not work.

    <textarea id='textarea'></textarea>

    $("#textarea").append(formatJSON(JSON.stringify(jsonobject),true));

    function formatJSON(json,textarea) {
        var nl;
        if(textarea) {
            nl = "&#13;&#10;";
        } else {
            nl = "<br>";
        }
        var tab = "&#160;&#160;&#160;&#160;";
        var ret = "";
        var numquotes = 0;
        var betweenquotes = false;
        var firstquote = false;
        for (var i = 0; i < json.length; i++) {
            var c = json[i];
            if(c == '"') {
                numquotes ++;
                if((numquotes + 2) % 2 == 1) {
                    betweenquotes = true;
                } else {
                    betweenquotes = false;
                }
                if((numquotes + 3) % 4 == 0) {
                    firstquote = true;
                } else {
                    firstquote = false;
                }
            }
    
            if(c == '[' && !betweenquotes) {
                ret += c;
                ret += nl;
                continue;
            }
            if(c == '{' && !betweenquotes) {
                ret += tab;
                ret += c;
                ret += nl;
                continue;
            }
            if(c == '"' && firstquote) {
                ret += tab + tab;
                ret += c;
                continue;
            } else if (c == '"' && !firstquote) {
                ret += c;
                continue;
            }
            if(c == ',' && !betweenquotes) {
                ret += c;
                ret += nl;
                continue;
            }
            if(c == '}' && !betweenquotes) {
                ret += nl;
                ret += tab;
                ret += c;
                continue;
            }
            if(c == ']' && !betweenquotes) {
                ret += nl;
                ret += c;
                continue;
            }
            ret += c;
        } // i loop
        return ret;
    }
    
    0 讨论(0)
提交回复
热议问题