我想将WhatsApp对话作为数组返回。 为此,我正在使用正则表达式,但是无法使其正常工作。
这是通过WhatsApp导出的聊天示例(已编辑):
6/13/18, 3:40 AM - Messages to this group are now secured with end-to-end encryption. Tap for more info.
6/13/18, 3:40 AM - You created group "Test Group"
6/13/18, 3:42 AM - Zack added Emma
6/13/18, 4:06 AM - Zack added Json
6/13/18, 2:35 PM - Zack: Let's meet tomorrow.
6/15/18, 5:34 PM - Emma: I'll create the Discord server by tonight.
We'll look into making the parser.
7/15/18, 12:05 PM - Zack: Great, I'll add that to our schedule.
7/15/18, 12:05 PM - Json: On our team calander - TCal?
7/15/18, 12:05 PM - Zack: Yes, added on 7/15/18, 12:05 PM.
7/15/18, 12:05 PM - Emma: Are we going JS on this?
7/15/18, 12:05 PM - Json: You bet.
7/15/18, 12:05 PM - Zack: JS is love, JS is life.
7/15/18, 1:46 PM - Emma: Haha.
7/15/18, 4:53 PM - Json:
我尝试了以下操作:
/\d{1,2}\/\d{1,2}\/\d{2},\s\d{1,2}:\d{2}\s[AP]M\s-.+\n?/g
正如您所期望的那样,它会给我以下内容: -
...但是,如果消息多于1行,则会被跳过。
例如
18年6月15日,下午5:34-艾玛:我将通过以下方式创建Discord服务器 今晚。
我们将研究解析器。
提取:
18年6月15日,下午5:34-艾玛:我将在今晚之前创建Discord服务器。
但是我希望它提取为:
Emma:我将在今晚之前创建Discord服务器。
我们将研究 进行解析器。
答案 0 :(得分:3)
您可以在正向超前使用您的(略微缩短)模式:
s.split(/(?=^\d{1,2}\/\d{1,2}\/\d{2},\s\d{1,2}:\d{2}\s[AP]M)/m).filter(Boolean)
请参见regex demo
此处,该模式将匹配紧跟\d{1,2}\/\d{1,2}\/\d{2},\s\d{1,2}:\d{2}\s[AP]M)
模式的每个行的起始位置。
JS演示:
var s = "6/13/18, 3:40 AM - Messages to this group are now secured with end-to-end encryption. Tap for more info.\r\n6/13/18, 3:40 AM - You created group \"Test Group\"\r\n6/13/18, 3:42 AM - Zack added Emma\r\n6/13/18, 4:06 AM - Zack added Json\r\n6/13/18, 2:35 PM - Zack: Let's meet tomorrow.\r\n6/15/18, 5:34 PM - Emma: I'll create the Discord server by tonight.\r\nWe'll look into making the parser.\r\n7/15/18, 12:05 PM - Zack: Great, I'll add that to our schedule.\r\n7/15/18, 12:05 PM - Json: On our team calander - TCal?\r\n7/15/18, 12:05 PM - Zack: Yes, added on 7/15/18, 12:05 PM.\r\n7/15/18, 12:05 PM - Emma: Are we going JS on this?\r\n7/15/18, 12:05 PM - Json: You bet.\r\n7/15/18, 12:05 PM - Zack: JS is love, JS is life.\r\n7/15/18, 1:46 PM - Emma: Haha.\r\n7/15/18, 4:53 PM - Json: ";
console.log(s.split(/(?=^\d{1,2}\/\d{1,2}\/\d{2},\s\d{1,2}:\d{2}\s[AP]M)/m).filter(Boolean));
如果添加.map(x => x.trim())
(或.map(function(x) { return x.trim(); })
),则可以修剪结果数组中的每个项目。
答案 1 :(得分:1)
效果很好,我只是想提醒一下,导出格式在很大程度上取决于您的系统语言。
例如02/12/12 11 PM(英语)与 23:00 12/02/12(德语)因此您当前的解决方案只能处理某些情况。
此外,系统消息或附件稍后会给您带来问题。
我在构建一个工具来分析 WhatsApp 聊天时遇到了同样的问题,并使用了一个 Javascript library,它使用了几乎涵盖所有极端情况的多个正则表达式:
过滤一般:
const regexParser = /^(?:\u200E|\u200F)*\[?(\d{1,4}[-/.] ?\d{1,4}[-/.] ?\d{1,4})[,.]? \D*?(\d{1,2}[.:]\d{1,2}(?:[.:]\d{1,2})?)(?: ([ap]\.? ?m\.?))?\]?(?: -|:)? (.+?): ([^]*)/i;
过滤系统消息:
const regexParserSystem = /^(?:\u200E|\u200F)*\[?(\d{1,4}[-/.] ?\d{1,4}[-/.] ?\d{1,4})[,.]? \D*?(\d{1,2}[.:]\d{1,2}(?:[.:]\d{1,2})?)(?: ([ap]\.? ?m\.?))?\]?(?: -|:)? ([^]+)/i;
日期:
const regexSplitDate = /[-/.] ?/;
处理附件,即使您导出不带附件的聊天,也会在“< >”中传递附件。 (例如
const regexAttachment = /<.+:(.+)>/;`