修复无效JSON的最有效方法

AaA*_*AaA 7 javascript c# json .net-4.0 fastjson

我陷入了一种不可能的境地.我有来自外太空的JSON(他们无法改变它).这是JSON

{
    user:'180111',
    title:'I\'m sure "E pluribus unum" means \'Out of Many, One.\' \n\nhttp://en.wikipedia.org/wiki/E_pluribus_unum.\n\n\'',
    date:'2007/01/10 19:48:38',
    "id":"3322121",
    "previd":112211,
    "body":"\'You\' can \"read\" more here [url=http:\/\/en.wikipedia.org\/?search=E_pluribus_unum]E pluribus unum[\/url]'s. Cheers \\*/ :\/",
    "from":"112221",
    "username":"mikethunder",
    "creationdate":"2007\/01\/10 14:04:49"
}
Run Code Online (Sandbox Code Playgroud)

我说,"它远不是一个有效的JSON".他们的反应是"嗯!但是Javascript可以毫无怨言地阅读它":

<html>
<script type="text/javascript">
    var obj = {"PUT JSON FROM UP THERE HERE"};

    document.write(obj.title);
    document.write("<br />");
    document.write(obj.creationdate + " " + obj.date);
    document.write("<br />");
    document.write(obj.body);
    document.write("<br />");
</script>
<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

问题

我应该通过.NET(4)读取和解析这个字符串,它破坏了Json.org的 C#部分中提到的14个库中的3个(没有尝试其余部分).为了解决问题,我编写了以下函数来解决单引号和双引号的问题.

public static string JSONBeautify(string InStr){
    bool inSingleQuote = false;
    bool inDoubleQuote = false;
    bool escaped = false;

    StringBuilder sb = new StringBuilder(InStr);
    sb = sb.Replace("`", "<°)))><"); // replace all instances of "grave accent" to "fish" so we can use that mark later. 
                                        // Hopefully there is no "fish" in our JSON
    for (int i = 0; i < sb.Length; i++) {
        switch (sb[i]) {

            case '\\':
                if (!escaped)
                    escaped = true;
                else 
                    escaped = false;
                break;
            case '\'':
                if (!inSingleQuote && !inDoubleQuote) {
                    sb[i] = '"';            // Change opening single quote string markers to double qoute
                    inSingleQuote = true;
                } else if (inSingleQuote && !escaped) {
                    sb[i] = '"';            // Change closing single quote string markers to double qoute
                    inSingleQuote = false;
                } else if (escaped) {
                    escaped = false;
                }
                break;
            case '"':
                if (!inSingleQuote && !inDoubleQuote) {
                    inDoubleQuote = true;   // This is a opening double quote string marker
                } else if (inSingleQuote && !escaped) {
                    sb[i] = '`';            // Change unescaped double qoute to grave accent
                } else if (inDoubleQuote && !escaped) {
                    inDoubleQuote = false; // This is a closing double quote string marker
                } else if (escaped) {
                    escaped = false;
                }
                break;
            default:
                escaped = false;
                break;
        }
    }
    return sb.ToString()
        .Replace("\\/", "/")        // Remove all instances of escaped / (\/) .hopefully no smileys in string
        .Replace("`", "\\\"")       // Change all "grave accent"s to escaped double quote \"
        .Replace("<°)))><", "`")   // change all fishes back to "grave accent"
        .Replace("\\'","'");        // change all escaped single quotes to just single quote
}
Run Code Online (Sandbox Code Playgroud)

现在JSONlint只抱怨属性名称,我可以使用JSON.NET和SimpleJSON库来解析JSON之上.

我确信我的代码不是修复提到的JSON的最佳方法.有没有我的代码可能会破坏的情况?有没有更好的方法呢?

Mou*_*ser 8

您需要通过JavaScript运行它.在.net中启动JavaScript解析器.将字符串作为JavaScript的输入并使用JavaScript的native JSON.stringify来转换:

obj = {
    "user":'180111',
    "title":'I\'m sure "E pluribus unum" means \'Out of Many, One.\' \n\nhttp://en.wikipedia.org/wiki/E_pluribus_unum.\n\n',
    "date":'2007/01/10 19:48:38',
    "id":"3322121",
    "previd":"112211",
    "body":"\'You\' can \"read\" more here [url=http:\/\/en.wikipedia.org\/?search=E_pluribus_unum]E pluribus unum[\/url]'s. Cheers \\*/ :\/",
    "from":"112221",
    "username":"mikethunder",
    "creationdate":"2007\/01\/10 14:04:49"
}

console.log(JSON.stringify(obj));
document.write(JSON.stringify(obj));
Run Code Online (Sandbox Code Playgroud)

请记住,您获得的字符串(或更确切的对象)是无效的JSON,无法使用JSON库进行解析.它需要首先转换为有效的JSON.但它是有效的JavaScript.

要完成此答案:您可以JavaScriptSerializer.Net中使用.对于此解决方案,您将需要以下程序集:

  • System.Net
  • System.Web.Script.Serialization

    var webClient = new WebClient();
    string readHtml = webClient.DownloadString("uri to your source (extraterrestrial)");
    var a = new JavaScriptSerializer();
    
    Dictionary<string, object> results = a.Deserialize<Dictionary<string, object>>(readHtml);
    
    Run Code Online (Sandbox Code Playgroud)