用于解析糟糕的JSON的lib - 它存在吗?

时间:2016-06-22 13:21:22

标签: javascript json

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

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

我需要一个lib,可以读到这个:

{hello: 1, bye:2, }

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

3 个答案:

答案 0 :(得分:1)

HJSON, the Human JSON看起来就像你想要的那样。他们可以采取一些"畸形的#34; JSON-esque语法和输出正确的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, '  ');
  });
});
&#13;
textarea {
  font-family: monospace;
}
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

不确定为什么需要它,但dirty-json似乎能够解析格式错误的JSON对象。另一种解决方案是在npm上使用public class MyApp extends Application { private static Context context; public void onCreate() { super.onCreate(); MyApplication.context = getApplicationContext(); } public static Context getAppContext() { return MyApplication.context; } 模块:https://www.npmjs.com/package/dirty-json

请您提供更多信息,了解您为何需要这样做,因为它可能是其他可以改进的地方。

答案 2 :(得分:1)

Haxe标准库中的交叉目标JSON解析器符合JSON规范。

您想要使用的json是无效的json,因此Haxe的标准解析器不支持它,因为Haxe的目的是构建健壮且无错误的项目。如果您需要处理损坏的数据,通常您有责任通过编写自己的解析器或修复错误数据来调用您的处理方式。 Haxe提供了大量工具来满足您的需求,但Haxe Foundation错误地避免了实施标准。 Haxe编译器通常可以帮助您了解数据是否已损坏,并且可以使用宏来加载或在编译时内联检查XML或JSON数据。

有关JSON解析结构的文档。    http://haxe.org/manual/std-Json-parsing.html

TJSON - 在Haxe中使用损坏的JSON

但对于“破碎”的JSON,似乎已经存在一个库。

https://github.com/martamius/TJSON

var jsonData = "{key:'value'}";
var object = TJSON.parse(jsonData);
trace(object.key); // outputs 'value'

所以我建议你尝试使用它,但有很多工具可以验证和检查你的JSON,也许这是一个更好的方法来坚持JSON规范,因为它无疑会提供更多的可预测性,并且会更可靠并且可能解析得更快。

但是如果您无法控制JSON数据并且使用TJSON时遇到任何问题,请告诉我们我确信Haxe是一个很好的方法。