使用键值对解析字符串响应并将其添加到映射或数组中

时间:2019-04-23 17:18:11

标签: java android regex string

我收到一个响应,该响应的键值对之间用:隔开

USER: 0xbb492894B403BF08e9181e42B07f76814b10FEdc
IP: 10.0.2.6
NETMASK: 255.255.0.0
SUPERNODE: tlcsupernode.ddns.net
PORT: 5000
COMMUNITY: tlcnet
PSK: mysecret
MAC: 00:02:ff:00:02:06

要解析和存储它们,我使用以下代码:

Map<String, String> map = new HashMap<String, String>();
String[] parts = response.trim().split(":");

for (int i = 0; i < parts.length; i += 2) {
    map.put(parts[i], parts[i + 1]);
}

for (String s : map.keySet()) {
    System.out.println(s + " is " + map.get(s));
    Log.d("Testing", "  "+s + " is " + map.get(s));
}

但是由于MAC具有多次:分隔符,所以我无法正确解析它。

我从以下链接获得了帮助: Split string into key-value pairs

4 个答案:

答案 0 :(得分:2)

使用Java 8流,您可以将其作为一个衬套来完成。

C:\Program Files\IBM\ILOG\CPLEX_Studio128\cplex\python

打印

String resp = "USER: 0xbb492894B403BF08e9181e42B07f76814b10FEdc\n" + 
        "IP: 10.0.2.6\n" + 
        "NETMASK: 255.255.0.0\n" + 
        "SUPERNODE: tlcsupernode.ddns.net\n" + 
        "PORT: 5000\n" + 
        "COMMUNITY: tlcnet\n" + 
        "PSK: mysecret\n" + 
        "MAC: 00:02:ff:00:02:06";

Map<String, String> map = Arrays.asList(resp.split("\\R")).stream().map(x -> x.split(":", 2)).collect(Collectors.toMap(x -> x[0], x -> x[1].trim()));

for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(String.format("Key: %s, Value: %s", entry.getKey(), entry.getValue()));
}

在这里,Key: SUPERNODE, Value: tlcsupernode.ddns.net Key: NETMASK, Value: 255.255.0.0 Key: COMMUNITY, Value: tlcnet Key: PORT, Value: 5000 Key: IP, Value: 10.0.2.6 Key: PSK, Value: mysecret Key: USER, Value: 0xbb492894B403BF08e9181e42B07f76814b10FEdc Key: MAC, Value: 00:02:ff:00:02:06 (与任何类型的换行符匹配)将您的响应字符串与换行符分开,然后使用\\R将第二个参数设置为2,以将字符串分开以得到最大两个值,最后通过:

被收集为Map

编辑:

对于Java的旧版本,您可以使用简单的for循环,

Collectors.toMap

答案 1 :(得分:1)

代替

String[] parts = response.trim().split(":");

执行以下操作:

String[] parts = response.trim().split(":", 2);

末尾的2将强制将字符串拆分为两个子字符串。像现在这样,不使用任何其他参数就意味着“分割成无数个子字符串”。

另外,在存储键和值之前,应修剪键和值,以防开头':'周围有空格

一个警告:假设其他':'字符将始终出现在值中,而不出现在键中。


有关更多详细信息,请参见here

答案 2 :(得分:1)

您只需将拆分的正则表达式更改为:\\s|\\n。有了这个,您正在使用的代码应该可以按预期工作。

另一种解决方案是先用\\R分割并分别处理每一行。为此,您可以使用line.split(":", 2)line.split(":\\s")。如果您需要更灵活的解决方案,则可以使用正则表达式来处理每一行。

Pattern pattern = Pattern.compile("(?<key>.+):\\s+(?<value>.+)");
Map<String, String> map = new HashMap<>();
for (String line : response.split("\\R")) {
    Matcher matcher = pattern.matcher(line);
    if (matcher.find()) {
        map.put(matcher.group("key"), matcher.group("value"));
    }
}

对于Java 8及更高版本,您可以使用Stream API:

Pattern pattern = Pattern.compile("(?<key>.+):\\s+(?<value>.+)");
Map<String, String> map2 = Arrays.stream(response.split("\\R"))
        .map(pattern::matcher)
        .filter(Matcher::find)
        .collect(Collectors.toMap(m -> m.group("key"), m -> m.group("value")));

答案 3 :(得分:0)

冒号和空格的组合看起来确实是唯一的,至少在您显示给我们的示例数据中。因此,尝试对此进行拆分:

String[] parts = response.split(":\\s+");
map.put(parts[0], parts[1]);