【问题标题】:parse a whatsApp conversation log解析 WhatsApp 对话日志
【发布时间】:2014-07-08 10:52:23
【问题描述】:

我正在尝试为 WhatsApp 的对话日志编写解析器。问题末尾的最小日志文件。

在这个日志中,有两种消息,普通的,语法是

date time: Name: Message

如您所见,Message 可以换行,名称可以包含:

第二种消息是“事件”消息,可以是以下类型:

date time: Name joined
date time: Name left
date time: Name was removed
date time: Name changed the subject to “GroupName”
date time: Name changed the group icon

我试着写了一些正则表达式,但我遇到的困难有几个:如何处理多行消息,如何解析Name字段(因为在:上拆分不起作用),如何构建一个正则表达式仅识别来自当前在组中的发件人的消息,最后如何解析特殊消息(例如,解析搜索 join as last word 这不是一个好主意)。

如何解析这样的日志文件并将所有内容移到字典中?

更准确地说,要回答评论中的问题,我正在考虑的输出类似于嵌套字典: 其中第一级的键是每个发送者,第二级区分“事件”(例如加入、离开等)和“消息”,并将所有内容作为元组列表。

>>>datab[Sender1]['Events']
>>>[('Joined',data1,time1),('Left',data2,time2]

>>>datab[Sender2]['Messages']
>>>[(data1,time1,Message1),(data2,time2,Message2)]

但如果你能想到更智能的格式,那就去吧!

29/03/14 15:48:05: John Smith changed the subject to “Test”

29/03/14 16:10:39: John Smith joined

29/03/14 16:10:40: Person:2 joined

29/03/14 16:10:40: John Smith: Hello!

29/03/14 16:11:40: Person:2: some random words,

29/03/14 16:12:40: Person3 joined

29/03/14 16:13:40: John Smith: Hello!Test message with newline
Another line of the same message
Another line.

29/03/14 16:14:43: Person:2: Test message using as last word joined

29/03/14 16:15:57: Person3 left

29/03/14 16:17:16: Person3 joined

29/03/14 16:18:21: Person:2 changed the group icon

29/03/14 16:19:16: Person3 was removed 

29/03/14 16:20:43: Person:2: Test message using as last word left

【问题讨论】:

  • 对于上述输入,您的预期输出是什么?
  • @Avinash 我正在编辑带有输出详细信息的问题

标签: python regex parsing


【解决方案1】:

你可以使用这个模式:

(?P<datetime>\d{2}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2}): (?P<name>\w+(?::\s*\w+)*|[\w\s]+?)(?:\s+(?P<action>joined|left|was removed|changed the (?:subject to “\w+”|group icon))|:\s(?P<message>(?:.+|\n(?!\n))+))

demo

为了处理多行消息,我禁止使用负前瞻连续换行符。但是,您可以通过在\n 之后添加下一个块的开头或字符串的结尾来使模式更加宽容。

【讨论】:

  • 看起来很不错,但是我发现另一个测试用例不起作用。如果我们在 : 之后放置一个空格,例如“John: Smith”,则正则表达式会中断
  • 这不适用于我今天所做的组导出。所以这是我为其他寻找它的人编辑的版本。 (?P&lt;datetime&gt;\d{4}\-\d{2}\-\d{2}\,\s*\d{1}:\d{2} [AaPp]\.[Mm]\.)\s*\-\s*(?P&lt;name&gt;\w+(?::\s*\w+)*|[\w\s]+?)\:\s(?:\s+(?P&lt;action&gt;joined|left|was removed|changed the (?:subject to “\w+â€|group icon))|(?P&lt;message&gt;(?:.+|\n(?!\d{4}\-\d{2}\-\d{2}\,\s*\d{1}:\d{2} [AaPp]\.[Mm]\.))+))
  • @shachna: 如果你想用 am 和 pm 描述日期时间格式,你必须用 ,\s*\d{1,2}:\d{2} 替换 ,\s*\d{1}:\d{2} 以允许小时数大于 9。(请注意,无论何时何地,量词 {1} 永远不需要,因为模式中的每个元素默认出现一次。)。 -: 不是特殊字符,不需要转义。另外:\s(?:\s+(?P&lt;action&gt; 至少需要连续的空格才能成功,你确定这部分吗?也许:\s(?:\s*(?P&lt;action&gt;
  • @CasimiretHippolyte 感谢您抓紧时间。我不确定空白位。我整天都在编辑我的 python 脚本,我认为那个版本的唯一问题是缺少时间位。
【解决方案2】:

迟到。

@Casimir 的回答来自 2014 年。现在 Whatsapp 消息的格式发生了一些变化。以下是更正后的正则表达式,但我没有介绍特殊消息部分(加入、离开、更改主题等)

(?<datetime>\d{1,2}\/\d{1,2}\/\d{1,4}, \d{1,2}:\d{1,2}( (?i)[ap]m)*) - (?<name>.*(?::\s*\w+)*|[\w\s]+?)(?:\s+(?<action>joined|left|was removed|changed the (?:subject to "\w+"|group's icon))|:\s(?<message>(?:.+|\n(?!\d{1,2}\/\d{1,2}\/\d{1,4}, \d{1,2}:\d{1,2}( (?i)[ap]m)*))+))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-29
    • 1970-01-01
    • 2014-03-23
    • 2016-01-09
    • 2014-11-01
    • 2023-04-01
    • 1970-01-01
    相关资源
    最近更新 更多