首页 > 解决方案 > C# 是否存在无效(脏)JSON 解析器?

问题描述

我有一个我无法控制的 JSON,需要定期检索它。80% 的时间它是有效的 JSON,但并非总是如此。

主要问题是:

我编写了一个函数来修复引号和空值,但非封闭对象让我发疯。

/// <summary>
/// 1. Escapes double quotes in json property values
/// 2. Replaces ":," with ":null,"
/// </summary>
public static string TryToFixJson(string invalidJsonStr)
{
    var invalidJson = new StringBuilder(invalidJsonStr);

    string[] stringStart =
    {
        "\":\"",
        "\": \""
    };
    string[] stringEnd =
    {
        "\",",
        "\"}",
        "\"]",
        "\",\""
    };

    foreach (string start in stringStart)
    {
        int lastStartIndex = -1,
            startIndex = invalidJson.IndexOf(start);

        // Fix non-string Json
        if (startIndex > -1)
        {
            string newJson = invalidJson.ToString(0, startIndex);
            newJson = FixNonStringJson(newJson);
            ReplaceStringPart(invalidJson, 0, startIndex, newJson);
        }

        while (startIndex != -1)
        {
            int endIndex = stringEnd
                .Select(end => invalidJson.IndexOf(end, startIndex + start.Length + 1))
                .Where(index => index != -1)
                .DefaultIfEmpty(-1)
                .Min();
            if (endIndex == -1)
            {
                break;
            }

            // Fix string
            int innerStringStart = startIndex + start.Length, innerStringLength = endIndex - innerStringStart;
            string newString = invalidJson.ToString(innerStringStart, innerStringLength);
            if (newString.IndexOf('\"') != -1)
            {
                newString = FixJsonString(newString);
                ReplaceStringPart(invalidJson, innerStringStart, innerStringLength, newString);
            }

            lastStartIndex = startIndex;
            startIndex = invalidJson.IndexOf(start, lastStartIndex + 1);

            // Fix non-string Json
            if (startIndex > -1)
            {
                int nonStringLength = startIndex - endIndex;
                string newJson = invalidJson.ToString(endIndex, nonStringLength);
                newJson = FixNonStringJson(newJson);
                ReplaceStringPart(invalidJson, endIndex, nonStringLength, newJson);

                startIndex = invalidJson.IndexOf(start, lastStartIndex + 1);
            }
        }
    }

    return invalidJson.ToString();
}

private static void ReplaceStringPart(StringBuilder stringToModify, int partStart, int partLength, string newString)
{
    stringToModify.Remove(partStart, partLength);
    stringToModify.Insert(partStart, newString);
}

private static string FixNonStringJson(string newJson)
{
    // Remove non-essential data
    string[] nonEssentialCharacters =
    {
        "\r",
        "\n",
        " ",
        "\t"
    };
    newJson = nonEssentialCharacters.Aggregate(newJson, (res, ch) => res.Replace(ch, ""));

    // Add null values instead of empty ones
    string[] noValue = 
    {
        ":,",
        ":]",
        ":}"
    };
    newJson = noValue.Aggregate(newJson, (res, nv) => res.Replace(nv, nv.Insert(1, "null")));

    return newJson;
}

private static string FixJsonString(string newString)
{
    newString = newString.Replace("\"", "\\\"");
    return newString;
}

C# 是否有一些无效的 JSON 解析器。我为 JS 找到了一个。它修复了除空值之外的所有内容,但我已经可以处理了。

编辑:更多信息来回答评论。

标签: c#json

解决方案


推荐阅读