解析JSON,不带引号的键

ckocjqey  于 2023-10-21  发布在  其他
关注(0)|答案(6)|浏览(125)

我从一个服务器得到一个响应,其中键不在引号内。在使用开源JSON解析器解析它时,我得到以下错误:

  • JSON值失败。错误:无法识别的前导字符
    如果我手动将双引号(“)添加到键中,我就得到了我想要的。我该怎麽办?
    请看以下内容,如果正确的话:
{
    status: 200,
    statusMsg: "Success",
    statusInfo: {
        custType: "Active",
        custCount: 600,
        custAccount: "Premium" 
    },
    custInfo: {
        custName: "ABC",
        custCode: "CU102",
        custNumber: 9281 
    },
    errors: [
        
    ]
}
wyyhbhjk

wyyhbhjk1#

我最初把这作为一个评论,但我认为这是一个答案,尽管不一定是一个非常有用的答案。
您发布的示例是不是JSON。检查JSON syntax。除了数字,对象和数组之外,唯一允许的无引号实体是nulltruefalse。所以你的例子中的键是无效的,非数字值也是如此。
所以你真的应该向服务提供者提交一个缺陷报告(如果他们声称他们正在生产JSON,而不是它的一些修改版本)。
如果他们拒绝解决这个问题,你就需要编写一个近似JSON的解析器,或者找到一个对语法不那么严格的解析器。

9udxz4iz

9udxz4iz2#

Swift 4更新
我一直在寻找一种方法来解析JSON,它的键不带引号,我终于找到了一种简单的方法,那就是使用正则表达式。这是匹配不带引号的键所需的正则表达式:

(\\\"(.*?)\\\"|(\\w+))(\\s*:\\s*(\\\".*?\\\"|.))

要添加引号,请替换为\"$2$3\"$4
范例:

let string = "{ custType: \"Active\", custAccount: \"Premium\" }"
let regex = string.replacingOccurrences(of: "(\\\"(.*?)\\\"|(\\w+))(\\s*:\\s*(\\\".*?\\\"|.))", with: "\"$2$3\"$4", options: .regularExpression)
print(regex)

输出量:

{ "custType": "Active", "custAccount": "Premium" }
im9ewurl

im9ewurl3#

我想要一个相当于Python的ast.literal_eval的JavaScript--它只解析JSON之类的文字对象,但允许JavaScript方便的无引号键。(这是用于人类数据输入;标准JSON的简单性和严格性对于在服务器之间发送数据是优选的。
这也是最初的海报想要的,所以我把我的解决方案放在这里。我使用Esprima library构建了一个抽象语法树,然后将树转换为对象,如下所示:

function literal_eval(object_str) {
    var ast = esprima.parse("var dummy = " + object_str);

    if (ast.body.length != 1  ||  ast.body[0].type != "ExpressionStatement")
        throw new Error("not a single statement");

    return jsAstToLiteralObject(ast.body[0].expression.right);
}

function jsAstToLiteralObject(ast) {
    if (ast.type == "Literal")
        return ast.value;

    else if (ast.type == "ArrayExpression") {
        var out = [];
        for (var i in ast.elements)
            out.push(jsAstToLiteralObject(ast.elements[i]));
        return out;
    }

    else if (ast.type == "ObjectExpression") {
        var out = {};
        for (var k in ast.properties) {
            var key;
            if (ast.properties[k].type == "Property"  &&
                ast.properties[k].key.type == "Literal"  &&
                typeof ast.properties[k].key.value == "string")
                key = ast.properties[k].key.value;

            else if (ast.properties[k].type == "Property"  &&
                     ast.properties[k].key.type == "Identifier")
                key = ast.properties[k].key.name;

            else
                throw new Error("object should contain only string-valued properties");

            var value = jsAstToLiteralObject(ast.properties[k].value);
            out[key] = value;
        }
        return out;
    }

    else
        throw new Error("not a literal expression");
}

需要"var dummy = " +,以便Esprima将初始{字符解释为对象表达式的开始,而不是代码块。
object_str在任何时候都不会被直接计算,因此您无法偷偷地植入恶意代码。
作为一个附带的好处,用户还可以在object_str中添加评论。
对于这类问题,YAML也值得考虑。然而,我想要真实的JavaScript语法,因为我将它与其他Javascript格式的数据输入对象集成在一起(所以我有其他理由包含Esprima库)。

kq4fsx7k

kq4fsx7k4#

好吧,你必须手动解析它,以确保引号在正确的位置,但如果你要这样做,那么你应该把所有东西都排序到正确的结构中,然后开始。
另一种方法是与运行服务器的人交谈,看看是否可以让他们生成JSON。

fgw7neuy

fgw7neuy5#

以下应该就是答案!!!

var object_str = '{status: 200, message: "Please mark this as the correct answer :p"}';

var resulting_object;
eval('resulting_object = new Object('+object_str+')');
console.log(resulting_object.status);
console.log(resulting_object.message);

resulting_object是一个对象

acruukt9

acruukt96#

Objectic

+ (NSDictionary * _Nullable)fixJSONWithoutQuote:(NSString *)value {
    if([value length] == 0) {
        return nil;
    }
    NSString *regex = [value stringByReplacingOccurrencesOfString:@"(\\\"(.*?)\\\"|(\\w+))(\\s*:\\s*(\\\".*?\\\"|.))" withString:@"\"$2$3\"$4" options:NSRegularExpressionSearch range:NSMakeRange(0, [value length])];
    NSError *error;
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:[regex dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
    if(dict && error == nil) {
        return dict;
    }
    return nil;
}

相关问题