从json对象中提取一些没有键的值

时间:2018-05-31 23:31:05

标签: json regex elasticsearch

我正在使用 java 从弹性搜索运行任务响应中提取节点ID列表。

响应看起来像这样

{
    "nodes": {
        "ZKUuxQZpRCCcJ0njBM1P0A": {
            "name": "ZKUuxQZ",
            "transport_address": "127.0.0.1:9300",
            "host": "127.0.0.1",
            "ip": "127.0.0.1:9300",
            "roles": [
                "master",
                "data",
                "ingest"
            ],
            "tasks": {
                "ZKUuxQZpRCCcJ0njBM1P0A:118": {
                    "node": "ZKUuxQZpRCCcJ0njBM1P0A",
                    "id": 118,
                    "type": "transport",
                    "action": "indices:data/write/delete/byquery",
                    "start_time_in_millis": 1527808643421,
                    "running_time_in_nanos": 154234724059,
                    "cancellable": true,
                    "headers": {}
                }
            }
        }
    }
}

在这个例子中,我想要确切ZKUuxQZpRCCcJ0njBM1P0A:118。有人能举例说明如何提取这些信息吗?

选项1, java json解析器。我想编写一个响应类并解析json字符串,但ZKUuxQZpRCCcJ0njBM1P0A:118不是key:value格式。我不知道如何提取它。

选项2,使用正则表达式。节点ID部分也可能包含-_。有人可以提供一个整洁的 java 正则表达式解决方案吗?到目前为止,我的正则表达式是[a-zA-Z0-9\-\_]+\:[0-9]+,我不确定这是否足够安全。

感谢。

3 个答案:

答案 0 :(得分:1)

一种方法是使用org.json库并创建JSONObject并使用keys(),您可以获取所有密钥并使用它来完成任务

在pom.xml中添加以下依赖项

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20180130</version>
</dependency>

然后您可以执行以下操作:

String jsonString = "{\n" +
        "    \"nodes\": {\n" +
        "        \"ZKUuxQZpRCCcJ0njBM1P0A\": {\n" +
        "            \"name\": \"ZKUuxQZ\",\n" +
        "            \"transport_address\": \"127.0.0.1:9300\",\n" +
        "            \"host\": \"127.0.0.1\",\n" +
        "            \"ip\": \"127.0.0.1:9300\",\n" +
        "            \"roles\": [\n" +
        "                \"master\",\n" +
        "                \"data\",\n" +
        "                \"ingest\"\n" +
        "            ],\n" +
        "            \"tasks\": {\n" +
        "                \"ZKUuxQZpRCCcJ0njBM1P0A:118\": {\n" +
        "                    \"node\": \"ZKUuxQZpRCCcJ0njBM1P0A\",\n" +
        "                    \"id\": 118,\n" +
        "                    \"type\": \"transport\",\n" +
        "                    \"action\": \"indices:data/write/delete/byquery\",\n" +
        "                    \"start_time_in_millis\": 1527808643421,\n" +
        "                    \"running_time_in_nanos\": 154234724059,\n" +
        "                    \"cancellable\": true,\n" +
        "                    \"headers\": {}\n" +
        "                }\n" +
        "            }\n" +
        "        }\n" +
        "    }\n" +
        "}";

JSONObject jsonObject = new JSONObject(jsonString);

Set<String> topLevelKeys = jsonObject.keySet();

for (String key : topLevelKeys) {
    Object value = jsonObject.get(key);

    if (value instanceof JSONObject) {
        JSONObject valueObject = jsonObject.getJSONObject(key);
        System.out.println(valueObject.toString());
    }
}

根据您的要求进行扩展。

答案 1 :(得分:0)

所以正则表达式太过于hacky而且我用gson想出来了。我希望ElasticSearch可以为我们提供一些标准库来提取各种响应。这是我使用gson的解决方案。

import com.google.gson.*;

import org.json.JSONObject;

公共课堂考试{

public static void main(String[] args) throws Exception {
    String jsonString = "json_format elasticsearch reponse for listing running tasks"
    JsonParser parser = new JsonParser();
    JsonObject jsonObject = parser.parse(content).getAsJsonObject();

    jsonObject.getAsJsonObject("nodes").entrySet().forEach(
            s -> {
                s.getValue().getAsJsonObject().getAsJsonObject("tasks").entrySet().forEach( s2 -> {
                    System.out.println(s2.getKey());
                });
            });
}

它会打印所有正在运行的任务ID,如下所示。它在技术上是nodeId:taskId,但ES在其任务API文档中有一个非常模糊的描述(它表示你可以使用TASK_ID来检查任务的状态,以及TASK_ID是nodeId:taskId)。

Mw-3i39gTHGxu5c8z9viQQ:503209021 DZ29LMsWR0aW9guWZTYe2Q:482931604 6CAbDZSWR8SfwZgnRT0qNg:494351185

答案 2 :(得分:0)

使用以下正则表达式:

[a-zA-Z0-9-_]*[0-9]+[a-zA-Z]+:[0-9]*

您可以在此处找到测试结果:

https://regexr.com/3qdug