操作 .txt WhatsApp 备份

Manipulate .txt WhatsApp backup

我一直在寻找一种方法来操纵 .txt WhatsApp 备份对话,但我现在卡住了。

我想将对话的日期时间、日期、时间、用户和消息保存到列表中。

这是 txt 的 "normal" 格式:

5/31/18, 11:18 AM - User1: Hey
5/31/18, 11:18 AM - User2: what's up!
5/31/18, 3:19 PM - User1: Not much. 

所以我很难接受这个解决方案:

while ((line = file.ReadLine()) != null)
            {
                if(line.Length > 0)
                {
                    list.Add(new Whatsapp()
                    {
                        DateTime= line.Substring(0, line.IndexOf("-")).Replace(",", "").Trim(),
                        Date= line.Substring(0, line.IndexOf(",")).Trim(),
                        Time= line.Substring(0, line.IndexOf("-")).Trim().Substring(line.Substring(0, line.IndexOf("-")).Trim().IndexOf(",") + 2),
                        User = line.Substring(line.IndexOf("-") + 2).Substring(0, line.Substring(line.IndexOf("-") + 2).IndexOf(":")).Trim(),
                        Message= line.Substring(line.IndexOf("-") + 2).Trim().Substring(line.Substring(line.IndexOf("-") + 2).Trim().IndexOf(":") + 2).Trim()

                    });
                }
            } 

它奏效了,直到我在同一对话中用户在消息中换行时遇到格式中断,如:

5/31/18, 11:18 AM - User1: Hey
5/31/18, 11:18 AM - User2: what's up! 
5/31/18, 3:19 PM - User1: Not much. 
5/31/18, 3:20 PM - User2: Oh well..
Am I being annoying
doing
this
?
5/31/18, 3:19 PM - User1: Yep :(

所以 file.ReadLine() 不再起作用了,我现在不知道如何解决这个问题。有什么建议么?

首先,我想说的是,根据假定的字符位置解析文件是一个可怕的想法,尤其是在您无法完全控制数据格式的情况下。它所需要的只是一些小的波动,你的整个事情不仅不会工作,而且可能会崩溃。话虽这么说...

while ((line = file.ReadLine()) != null)
{
    if (line.Length <= 0)
    {
        continue;
    }

    var firstComma = line.IndexOf(",");

    if (firstComma >= 0)
    {
        var possibleDate = line.Substring(0, firstComma);
        if (DateTime.TryParse(possibleDate, out _))
        {
            list.Add(new Whatsapp
            {
                DateTime = line.Substring(0, line.IndexOf("-")).Replace(",", "").Trim(),
                Date = line.Substring(0, line.IndexOf(",")).Trim(),
                Time = line.Substring(0, line.IndexOf("-")).Trim().Substring(line.Substring(0, line.IndexOf("-")).Trim().IndexOf(",") + 2),
                User = line.Substring(line.IndexOf("-") + 2).Substring(0, line.Substring(line.IndexOf("-") + 2).IndexOf(":")).Trim(),
                Message = line.Substring(line.IndexOf("-") + 2).Trim().Substring(line.Substring(line.IndexOf("-") + 2).Trim().IndexOf(":") + 2).Trim()
            });
        }
        else
        {
            list.Last().Message += $"{line.Trim()}\r\n";
        }
    }
    else
    {
        list.Last().Message += $"{line.Trim()}\r\n";
    }
}

它很大,很丑,坦率地说,我不同意你在那里所做的一半,但它会做你想做的。

为了准确说明它在你已经做的之外做了什么,因为它遍历每一行,它检查是否有逗号,如果没有,那么它假定它应该是消息的一部分最后一行(危险动作编号 1)。如果有逗号,则它会尝试将该逗号之前的文本解析为日期时间,如果不能,则它再次假定它是最后一行消息的一部分(危险操作编号 2)。否则它的行为与您所写的一样。

不相关的评论,为什么要将 DateTime 的内容存储为 string?您分配给对象的子字符串行几乎不可读,您可能想重新访问这些行。但由于这些不在问题的范围内,我就把它们留在这里作为思考的食物。

再一次,我知道我的添加并不漂亮,但再一次将字符串解析成东西从来都不是。