从字符串中获取JSON对象的最佳方法

3

我有一个包含JSON对象的字符串。如何查找它是否包含JSON对象并提取它?除了按字符拆分,是否有更好的方法?

"String Notify : {"id": "1234", "transactionId": "TR-001", "timestamp": "1575445871"} with result success"

如果它是一个单独的JSON对象,并且周围没有其他花括号,您可以尝试获取indexOf('{')lastIndexOf('}')+1之间的substring() - tevemadar
你可以使用正则表达式检查字符串中的 JSON 发生情况,然后对值进行子字符串处理并将结果转换为 JSON 对象。 - user2342558
@tevemadar,你能把示例作为答案发布吗,这样我就可以接受它了。 - Syed
@user2342558,请提供答案,这样我就可以接受并点赞。 - Syed
我很确定@tevemadar建议不要使用具有不平衡或嵌套括号的输入,例如aaa { aaa {"id": 123} aaa。正则表达式也是如此,我认为您不能将其用于更复杂的情况。 - Karol Dowbecki
@KarolDowbecki 我猜这是日志文件的某个部分,重点不在于正确处理所有可能的字符序列,而只是从一行中获取已知的JSON部分。 - tevemadar
4个回答

3

使用last/IndexOf()的简单版本:

String testData="String Notify : {\"id\": \"1234\", \"transactionId\": \"TR-001\", \"timestamp\": \"1575445871\"} with result success";
int jsonStart=testData.indexOf('{');
int jsonEnd=testData.lastIndexOf('}')+1;
if(jsonStart>=0 && jsonEnd>jsonStart) {
    String jsonPart=testData.substring(jsonStart,jsonEnd);
    System.out.println(jsonPart);
}

测试:https://ideone.com/rgiH10

但是这段代码只能从较大的字符串中获取类似于序列化JSON对象的部分,解析则需要另外进行处理。


谢谢。解析工作交给我吧 :) 我会处理的。 - Syed

2

一种能够处理嵌套和不平衡对象,并返回对应于第一个最外层JSON对象的子字符串的解决方案:

int depth=0;
StringBuilder currentJsonString=new StringBuilder();
boolean containsValidJson = false;
for (char c: input.toCharArray()) {
    if (c == '{') { depth++; }
    else if (c == '}' && depth > 0) { // if depth==0, the } isn't part of a JSON object
        depth--;
        if (depth == 0) {
            currentJsonString.append(c);
            containsValidJson = true;
            break;
        }
    }
    if (depth > 0) { currentJsonString.append(c); }
}
// at this point if containsValidJson is true, call currentJsonString.toString() to get the JSON object

您可以在此处尝试

请注意,它不会验证JSON的其他功能,仅验证正确的括号。如果您想验证它,请将提取的子字符串传递给适当的JSON解析器。


1

在Java中,您可以使用许多方法来完成此操作:

方法1:GSON
Google的Gson是一个开源库,用于处理Java程序中的JSON。

Gson g = new Gson();
Player p = g.fromJson(jsonString, Player.class)

方法二:Jackson
Jackson是Java世界中最受欢迎的JSON解析库。它快速且功能丰富。

Player ronaldo = new ObjectMapper().readValue(jsonString, Player.class);

显然,对于他们来说,您需要了解JSON字符串的格式并创建一个具有这些属性的类(例如Player.class)。如果JSON的格式未知,则必须手动拆分。

0

这不是一个很好的解决方案,但它可以工作。您可以改进正则表达式,以自动包含花括号而不是将它们连接起来。

        String x="String Notify : {\"id\": \"1234\", \"transactionId\": \"TR-001\", \"timestamp\": \"1575445871\"} with result success";
        Pattern logEntry = Pattern.compile("(?<=\\{)([^\\}]+)(?=\\})");
        Matcher matchPattern = logEntry.matcher(x);

        while(matchPattern.find()) {
            String json = "{" + matchPattern.group(1) + "}";
            try {
                JSONObject jsonObject = new JSONObject(json);
                System.out.println("Found a json");
           }catch (JSONException err){
                err.printStackTrace();
           }
        }

别忘了将 org.json 添加到你的库中


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接