Разберите строковый ответ, используя пару ключ-значение, и добавьте их в карту или массив - PullRequest
1 голос
/ 23 апреля 2019

Я получаю ответ, в котором пары ключей и значений разделены :

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 имеет многократный разделитель :, я не могу его правильно проанализировать.

Я получил помощь по ссылке ниже: Разделить строку на пары ключ-значение

Ответы [ 4 ]

2 голосов
/ 23 апреля 2019

Используя потоки Java 8, вы можете сделать это как один слой.

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 с использованием Collectors.toMap

Изменить:

Для более старой версии Java вы можете использовать простой цикл for,

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 = new HashMap<>();

for (String line : resp.split("\\R")) {
    String[] keyValue = line.split(":", 2);
    map.put(keyValue[0], keyValue[1]);
}

for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(String.format("Key: %s, Value: %s", entry.getKey(), entry.getValue()));
}
1 голос
/ 23 апреля 2019

Вы можете просто изменить свое регулярное выражение на :\\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")));
1 голос
/ 23 апреля 2019

вместо

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

Сделайте это:

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

То, что 2 в конце заставит строку разбиваться только на две подстроки. Использование дополнительных параметров, которые вы делаете в настоящее время, означает «разбить на неограниченное количество подстрок».

Кроме того, вам следует обрезать ключи и значения перед их сохранением на случай, если вокруг начальных значений есть пробелы ':'

Одно предупреждение: предполагается, что дополнительные символы ':' всегда будут присутствовать в значении, а не в ключе.


Подробнее см. здесь .

0 голосов
/ 23 апреля 2019

Сочетание двоеточия и пробела кажется уникальным, по крайней мере, в приведенных нами примерах данных. Итак, попробуйте разделить на это:

String[] parts = response.split(":\\s+");
map.put(parts[0], parts[1]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...