javascript - 一个用于解析糟糕 JSON 的库 - 它存在吗?

标签 javascript json

我需要一个库,能够读取和解析自由格式的 JSON,例如对象,这将是正确的 JavaScript 对象,例如格式良好的 JSON 是这样的:

{"hello": 1, "bye":2}

我需要一个可以读取以下内容的库:

{hello: 1, bye:2, }

这在 JavaScript 和 Haxe 环境中是完全正确的,不是吗?那么为什么没有解析器支持它呢?自己写是没有问题的,但是首先我们先看看它是否已经存在。

最佳答案

HJSON, the Human JSON看起来就是你想要的。它们可以采用一些“格式错误”的 JSON 式语法并输出正确的 JSON。

/*! @preserve
 * Hjson v2.0.0
 * http://hjson.org
 *
 * Copyright 2014-2016 Christian Zangl, MIT license
 * Details and documentation:
 * https://github.com/laktak/hjson-js
 *
 * This code is based on the the JSON version by Douglas Crockford:
 * https://github.com/douglascrockford/JSON-js (json_parse.js, json2.js)
 */
var Hjson=function(){"use strict";var r="\n",e=!1,n=function(r,e){function n(){return u=r.charAt(a),a++,u}var t,u,f="",o=0,i=!0,a=0;for(n(),"-"===u&&(f="-",n());u>="0"&&"9">=u;)i&&("0"==u?o++:i=!1),f+=u,n();if(i&&o--,"."===u)for(f+=".";n()&&u>="0"&&"9">=u;)f+=u;if("e"===u||"E"===u)for(f+=u,n(),("-"===u||"+"===u)&&(f+=u,n());u>="0"&&"9">=u;)f+=u,n();for(;u&&" ">=u;)n();return e&&(","===u||"}"===u||"]"===u||"#"===u||"/"===u&&("/"===r[a]||"*"===r[a]))&&(u=0),t=+f,u||o||!isFinite(t)?void 0:t},t=function(){function r(){u=0,f=" "}function e(r){return"{"===r||"}"===r||"["===r||"]"===r||","===r||":"===r}var t,u,f,o,i={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:"	"},a=function(r){var e,n=0,f=1;for(e=u-1;e>0&&"\n"!==t[e];e--,n++);for(;e>0;e--)"\n"===t[e]&&f++;throw new Error(r+" at line "+f+","+n+" >>>"+t.substr(u-n,20)+" ...")},c=function(r){return r&&r!==f&&a("Expected '"+r+"' instead of '"+f+"'"),f=t.charAt(u),u++,f},s=function(r){return t.charAt(u+r)},l=function(){var r,e,n,t="";if('"'===f)for(;c();){if('"'===f)return c(),t;if("\\"===f)if(c(),"u"===f){for(n=0,e=0;4>e&&(r=parseInt(c(),16),isFinite(r));e++)n=16*n+r;t+=String.fromCharCode(n)}else{if("string"!=typeof i[f])break;t+=i[f]}else t+=f}a("Bad string")},p=function(){for(var r="",e=0,n=0;;){var t=s(-n-5);if(!t||"\n"===t)break;n++}for(var u=function(){for(var r=n;f&&" ">=f&&"\n"!==f&&r-->0;)c()};f&&" ">=f&&"\n"!==f;)c();for("\n"===f&&(c(),u());;){if(f){if("'"===f){if(e++,c(),3===e)return"\n"===r.slice(-1)&&(r=r.slice(0,-1)),r;continue}for(;e>0;)r+="'",e--}else a("Bad multiline string");"\n"===f?(r+="\n",c(),u()):("\r"!==f&&(r+=f),c())}},h=function(){if('"'===f)return l();for(var r="",n=u,t=-1;;){if(":"===f)return r?t>=0&&t!==r.length&&(u=n+t,a("Found whitespace in your key name (use quotes to include)")):a("Found ':' but no key name (for an empty key name use quotes)"),r;" ">=f?f?0>t&&(t=r.length):a("Found EOF while looking for a key name (check your syntax)"):e(f)?a("Found '"+f+"' where a key name was expected (check your syntax or use quotes if the key name includes {}[],: or whitespace)"):r+=f,c()}},d=function(){for(;f;){for(;f&&" ">=f;)c();if("#"===f||"/"===f&&"/"===s(0))for(;f&&"\n"!==f;)c();else{if("/"!==f||"*"!==s(0))break;for(c(),c();f&&("*"!==f||"/"!==s(0));)c();f&&(c(),c())}}},y=function(){var r=f;for(e(f)&&a("Found a punctuator character '"+f+"' when excpecting a quoteless string (check your syntax)");;){if(c(),3===r.length&&"'''"===r)return p();var t="\r"===f||"\n"===f||""===f;if(t||","===f||"}"===f||"]"===f||"#"===f||"/"===f&&("/"===s(0)||"*"===s(0))){var u=r[0];switch(u){case"f":if("false"===r.trim())return!1;break;case"n":if("null"===r.trim())return null;break;case"t":if("true"===r.trim())return!0;break;default:if("-"===u||u>="0"&&"9">=u){var o=n(r);if(void 0!==o)return o}}if(t)return r.trim()}r+=f}},b=function(r){var e;for(r--,e=u-2;e>r&&t[e]<=" "&&"\n"!==t[e];e--);"\n"===t[e]&&e--,"\r"===t[e]&&e--;var n=t.substr(r,e-r+1);for(e=0;e<n.length;e++)if(n[e]>" ")return n;return""},g=function(){var r,e,n=[];if(o&&(Object.defineProperty&&Object.defineProperty(n,"__WSC__",{enumerable:!1,writable:!0}),n.__WSC__=r=[]),c(),e=u,d(),r&&r.push(b(e)),"]"===f)return c(),n;for(;f;){if(n.push(x()),e=u,d(),","===f&&(c(),e=u,d()),r&&r.push(b(e)),"]"===f)return c(),n;d()}a("End of input while parsing an array (did you forget a closing ']'?)")},v=function(r){function e(r){t.c[r]=b(i),r&&t.o.push(r)}var n,t,i,s={};if(o&&(Object.defineProperty&&Object.defineProperty(s,"__WSC__",{enumerable:!1,writable:!0}),s.__WSC__=t={c:{},o:[]},r&&(t.noRootBraces=!0)),r?i=1:(c(),i=u),d(),t&&e(""),"}"===f&&!r)return c(),s;for(;f;){if(n=h(),d(),c(":"),s[n]=x(),i=u,d(),","===f&&(c(),i=u,d()),t&&e(n),"}"===f&&!r)return c(),s;d()}return r?s:void a("End of input while parsing an object (did you forget a closing '}'?)")},x=function(){switch(d(),f){case"{":return v();case"[":return g();case'"':return l();default:return y()}},m=function(){switch(d(),f){case"{":return v();case"[":return g()}try{return v(!0)}catch(e){r();try{return x()}catch(n){throw e}}};return function(e,n){var u;return o=n&&n.keepWsc,t=e,r(),u=m(),d(),f&&a("Syntax error, found trailing characters"),u}}(),u=function(){function t(r){return" ">=r}function u(r){return r.replace(d,function(r){var e=v[r];return"string"==typeof e?e:"\\u"+("0000"+r.charCodeAt(0).toString(16)).slice(-4)})}function f(r,e,f,i){if(!r)return'""';y.lastIndex=0,g.lastIndex=0;var a=p||f||y.test(r),c=r[0],s=r[r.length-1];return a||t(c)||'"'===c||"'"===c&&"'"===r[1]&&"'"===r[2]||"#"===c||"/"===c&&("*"===r[1]||"/"===r[1])||"{"===c||"["===c||t(s)||void 0!==n(r,!0)||g.test(r)?(d.lastIndex=0,b.lastIndex=0,d.test(r)?b.test(r)||i?'"'+u(r)+'"':o(r,e):'"'+r+'"'):r}function o(r,e){var n,t=r.replace(/\r/g,"").split("\n");if(e+=k,1===t.length)return"'''"+t[0]+"'''";var u=c+e+"'''";for(n=0;n<t.length;n++)u+=c,t[n]&&(u+=e+t[n]);return u+c+e+"'''"}function i(r){return r?x.test(r)?(d.lastIndex=0,'"'+(d.test(r)?u(r):r)+'"'):r:'""'}function a(r,e,n,t){function u(r){return r&&"\n"===r["\r"===r[0]?1:0]}function o(r){return r&&!u(r)}function p(r){if(!r)return"";for(var e=0;e<r.length;e++){var n=r[e];if("\n"===n||"#"===n||"/"===n&&("/"===r[e+1]||"*"===r[e+1]))break;if(n>" ")return" # "+r}return r}switch(typeof r){case"string":return f(r,m,e,t);case"number":return isFinite(r)?String(r):"null";case"boolean":return String(r);case"object":if(!r)return"null";var d,y;s&&(d=r.__WSC__);var b="[object Array]"===Object.prototype.toString.apply(r),g=b||!t||(d?!d.noRootBraces:h),v=m;g&&(m+=k);var x,j,w,_,O=c+v,S=c+m,E=n||l?"":O,F=[];if(b){for(x=0,j=r.length;j>x;x++)d&&F.push(p(d[x])+S),F.push(a(r[x],d?o(d[x+1]):!1,!0)||"null");d&&F.push(p(d[x])+O),_=d?E+"["+F.join("")+"]":0===F.length?"[]":E+"["+S+F.join(S)+O+"]"}else{if(d){y=p(d.c[""]);var W=d.o.slice();for(w in r)Object.prototype.hasOwnProperty.call(r,w)&&W.indexOf(w)<0&&W.push(w);for(x=0,j=W.length;j>x;x++)w=W[x],(g||x>0||y)&&F.push(y+S),y=p(d.c[w]),_=a(r[w],o(y)),_&&F.push(i(w)+(u(_)?":":": ")+_);(g||y)&&F.push(y+O)}else for(w in r)Object.prototype.hasOwnProperty.call(r,w)&&(_=a(r[w]),_&&F.push(i(w)+(u(_)?":":": ")+_));_=0===F.length?"{}":g?d?E+"{"+F.join("")+"}":E+"{"+S+F.join(S)+O+"}":F.join(d?"":S)}return m=v,_}}var c,s,l,p,h,d=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,y=/[\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,b=/'''|[\x00-\x09\x0b\x0c\x0e-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,g=/^(true|false|null)\s*((,|\]|\}|#|\/\/|\/\*).*)?$/,v={"\b":"\\b","	":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},x=/[,\{\[\}\]\s:#"]|\/\/|\/\*|'''/,m="",k="  ";return function(n,t){var u,f;if(c=r,k="  ",s=!1,l=e,h=!0,p=!1,t&&"object"==typeof t&&(("\n"===t.eol||"\r\n"===t.eol)&&(c=t.eol),f=t.space,s=t.keepWsc,l=t.bracesSameLine||e,h=t.emitRootBraces,p="always"===t.quotes),"number"==typeof f)for(k="",u=0;f>u;u++)k+=" ";else"string"==typeof f&&(k=f);return a(n,null,!0,!0)}}();return{parse:t,stringify:u,endOfLine:function(){return r},setEndOfLine:function(e){("\n"===e||"\r\n"===e)&&(r=e)},bracesSameLine:function(){return e},setBracesSameLine:function(r){e=r},rt:{parse:function(r,e){return(e=e||{}).keepWsc=!0,t(r,e)},stringify:function(r,e){return(e=e||{}).keepWsc=!0,u(r,e)}}}}();if("object"==typeof module){if("function"==typeof require){var os=require("os");Hjson.setEndOfLine(os.EOL)}module.exports=Hjson}


function ready(fn) {
  if (document.readyState != 'loading') {
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}

ready(function() {
  var button = document.getElementById('convert');
  button.addEventListener('click', function() {
    // When we click out button, convert the "bad" json into actual json
    var hjson_text = document.querySelector('.hjson').value;
    
    var converted_text = Hjson.parse(hjson_text);
    
    document.querySelector('.json').value = JSON.stringify(converted_text, null, '  ');
  });
});
textarea {
  font-family: monospace;
}
<textarea rows="8" cols="30" class="hjson" id="hjson">
  {
    'dontWorry': 123,
    "about a thing": 4,
    becauseEverything: [6,5,4]
    WillBeAlright: {a:1},
  }
</textarea>
<textarea rows="8" cols="30" class="json" readonly></textarea>

<div><button id="convert">
Convert HJSON to JSON
</button></div>

关于javascript - 一个用于解析糟糕 JSON 的库 - 它存在吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37969362/

相关文章:

javascript - 如何在 ember.js 中将多个模型处理到模板/路由中

javascript - Typescript:静态方法返回值

php - json_encode url 失败

javascript - 如何在 JavaScript 中同步运行函数?

javascript - 如何在 JavaScript 中创建未初始化的对象?

javascript - 滚动到相对于 anchor 的位置

php - Steam API 以 json 形式获取组

c# - ASP WebApi : Prettify ActionResult JSON output

android - 使用 JSON 数组 Android 加载更多列表

javascript - json的ajax响应限制是多少?