Whatsapp 将历史解析为对话框 json

Whatsapp parse history to dialog json

所以我有这个 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
      }
    },
    ...
  ]
}

更重要的是,首先消息将分为三个部分:

发生的另一件事是响应,它选择一个主要人物(在本例中 "Person A")。然后它从顶部开始查看每条消息,查找该人(称为 "Main-Message")的第一条消息。如果它找到一个,它将寻找另一个人的响应(下一条消息(称为"Response"))。如果下一条消息再次来自主要人物,它将选择该消息作为 "Main-Message" 并寻找下一条消息。

示例:

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

在这个例子中,我们将选择 "Person A" 作为我们的主角。第一条消息是由我们的主要人物撰写的,因此它将是我们的主要消息。下一条消息来自其他人,因此这将是我们的回复。

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

下一条消息又是我们的主要人物,所以我们就把它作为我们的主要消息。但是之后的消息是 not 的,所以我们将跳过之前的消息。 之后的信息又是我们对手,所以这就是我们的回应。

{
    "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
            }
        }
    ]
}

有几个问题:

您可能已经从我的标签中猜到了,我使用的语言是 Java。

如有任何疑问或不清楚的信息,请随时提请我注意。

我自己做的。首先,我做了一个 Class 命名为 "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;
    }

}

这个Class有解析消息的任务。

这就是我们合并多行消息的方式:

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);
    }
}

这是 Class 的用法:

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;
    }
}