WhatsApp анализ истории в диалоговом окне JSON - PullRequest
0 голосов
/ 19 сентября 2018

Итак, у меня есть файл журнала WhatsApp, который выглядит следующим образом: (метки времени не точные)

[15.11.16, 16:13:29] Person A: Hello
[15.11.16, 16:13:45] Person B: This is
a multiline
message
[15.11.16, 16:14:12] Person A: Wow, so cool ?

Я хочу проанализировать их в формате json, который будет выглядеть так:

{
  "msg": [
    {
      "sender": "Person A",
      "message": "Hello",
      "time": 1479205511000,
      "response": {
        "sender": "Person B",
        "message": "This is\na multiline\nmessage",
        "time": 1479205536000
      }
    },
    ...
  ]
}

Что происходит, прежде всего сообщение будет разбито на три части:

  • Время (как отметка времени)
  • Имя человека
  • Сообщение (Если это многострочное сообщение, символы новой строки должны быть экранированы)

Другая вещь, которая происходит, - это вещь ответа, которая выбирает одного главного человека (в данном случае «персона А»),Затем он просматривает каждое сообщение, начинающееся сверху, и ищет первое сообщение от этого человека (называемое «Main-Message»).Если он находит один, он будет искать ответ другого человека (следующее сообщение (называется «Ответ»)).Если следующее сообщение снова от основного лица, оно выберет это сообщение как «Основное сообщение» и будет искать следующее.

Пример:

Person A: Hi
Person B: Hi
Person A: This is cool
Person A: I am cool
Person B: Ah ok

В этом примереМы выберем «Персона А» в качестве нашего Главного лица.Первое сообщение написано нашим Главным лицом, поэтому оно будет нашим Главным сообщением.Следующее сообщение от другого лица, так что это будет наш ответ.

{
    "sender":"Person A",
    "message":"Hi",
    "time":1479205511000,
    "response":{
        "sender":"Person B",
        "message":"Hi",
        "time":1479205536000
    }
}

Следующее сообщение снова от нашего главного лица, поэтому мы примем его в качестве основного сообщения.Но сообщение после этого не от другого лица, поэтому мы пропустим сообщение раньше.Сообщение после этого снова получено от нашего оппонента , так что это будет наш ответ.

{
    "sender":"Person A",
    "message":"I am cool",
    "time":1479205511000,
    "response":{
        "sender":"Person B",
        "message":"Ah ok",
        "time":1479205536000
    }
}

Теперь у нас есть такой JSON:

{
    "msg":[
        {
            "sender":"Person A",
            "message":"Hi",
            "time":1479205511000,
            "response":{
                "sender":"Person B",
                "message":"Hi",
                "time":1479205536000
            }
        },
        {
            "sender":"Person A",
            "message":"I am cool",
            "time":1479205511000,
            "response":{
                "sender":"Person B",
                "message":"Ah ok",
                "time":1479205536000
            }
        }
    ]
}

ТамЕсть пара проблем:

  • Многострочные сообщения
  • Не UTF-8 Символы, такие как '?', которые следует экранировать -> Кодировка текста
  • Огромные журналы (до100.000 строк) -> Производительность
  • Иногда строки начинаются с управляющих символов, поэтому что-то вроде String.starts не всегда работает идеально

Как вы могли догадаться по моим тегам, языкя использую Java.

Если есть какие-либо вопросы или неясная информация, не стесняйтесь обращать на это мое внимание.

1 Ответ

0 голосов
/ 19 сентября 2018

Я просто сделал это сам.Прежде всего, я создал класс с именем «Message»:

public class Message {

    public String sender;

    public String time;

    public String message;

    public String plainMessage;

    public Message(String line) {
        String[] array = line.split("]");

        time = clean(array[0].replace("[", ""));

        array = Main.removeElements(array, array[0]);

        line = Main.join("]", array);

        array = line.split(":");

        sender = clean(array[0]);

        array = Main.removeElements(array, array[0]);

        line = Main.join(":", array);

        plainMessage = line;

        line = StringEscapeUtils.escapeJava(line);
        line = escapeUmlaut(line);

        message = StringEscapeUtils.escapeJson(line);
    }

    private String escapeUmlaut(String input) {
        String output = input.replace("ü", "ue")
                .replace("ö", "oe")
                .replace("ä", "ae")
                .replace("ß", "ss");

        output = output.replace("Ü(?=[a-zäöüß ])", "Ue")
                .replace("Ö(?=[a-zäöüß ])", "Oe")
                .replace("Ä(?=[a-zäöüß ])", "Ae");

        output = output.replace("Ü", "UE")
                .replace("Ö", "OE")
                .replace("Ä", "AE");

        return output;
    }

    public static String clean(String what) {
        char[] chars = what.toCharArray();
        what = "";
        char[] allowed = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890[](){}=?!\\§$%&/'#*+;,:.-_<>|".toCharArray();
        for (char c : chars) {
            for (char cc : allowed) {
                if (cc == c) {
                    what += c;
                }
            }
        }

        return what;
    }

}

Этот класс имеет задачу для анализа сообщения.

Вот как мы объединяем многострочные сообщения:

ArrayList <String> parsed = new ArrayList <String> ();

for (int x = 0; x < size; x++) {
    String line = list.get(x);

    if (startsWith(line, '[')) {
        parsed.add(line);
    } else {
        int lastn = parsed.size() - 1;
        String last = parsed.get(lastn);
        last += "\\n" + line;
        parsed.set(lastn, last);
    }
}

Вот как используется класс:

Message MainMessage = null;

String json = "";

boolean firstWrite = false;

final Pattern pattern = Pattern.compile("[a-zA-Z0-9]+", Pattern.MULTILINE);

for (int x = 0; x < size; x++) {
    result = "";
    progressBar.setValue(x);

    String line = parsed.get(x);

    if (config.debug) {
        System.out.println(line);
    }

    Message message = new Message(line);
    final Matcher matcher = pattern.matcher(message.plainMessage);

    if (!matcher.find()) {
        continue;
    }

    if (x == 0 && mainSender == null) {
        mainSender = message.sender;
        MainMessage = message;
        continue;
    }

    if (mainSender.equals(message.sender)) {
        MainMessage = message;
    } else if (message.sender != mainSender && MainMessage != null) {
        json = "\n{\"sender\": \"" + MainMessage.sender + "\", \"message\": \"" + MainMessage.message + "\", \"response\": ";
        json += "{\"sender\": \"" + message.sender + "\", \"message\": \"" + message.message + "\"}}";
        if (firstWrite) {
            json = "," + json;
        }

        Files.write(Paths.get(
            export), json.getBytes(), StandardOpenOption.APPEND);
        json = "";
        MainMessage = null;

        firstWrite = true;
    }
}
...