Я хотел бы извлечь все шаблоны, соответствующие сообщению в WhatsApp. Сообщения имеют следующий вид:
Однострочное сообщение:
[19.09.17, 19:54:48] Marc: If the mean is not in the thousands, there's the problem
Многострочное длинное сообщение:
[19.09.17, 19:54:59] Joe: > mean(aging$Population)
[1] 1593.577
Is what I get as solution
Мне удалось разделить его на дату, время, отправителя и сообщение, но только для однострочных, сначала прочитав строку текстового файла для строки, а затем разделив эти строки на разные разделители. Однако это не работает для сообщений с несколькими строками. Теперь я пытаюсь использовать регулярные выражения, с помощью которых мне удалось получить дату и время, но я все еще пытаюсь расширить шаблон для сообщений на несколько строк.
## reg expressions to match different things in the log
date = r'\[\d+\.\d+\.\d+,'
time = r'\d+\:\d+\:\d+]'
message = r':\s+.+\['
message = re.compile(message, re.DOTALL)
Обратите внимание, что мой журнал взят из немецкого WhatsApp, поэтому даты немного другие. Также я закончил на, и], чтобы случайно не получить совпадения из сообщений.
Я хотел бы сделать то же самое с шаблоном сообщения, заканчившись на [, который обычно является началом следующей строки (но может быть не очень надежным, если его можно найти в сообщении на новой строке).
Вероятно, есть более простое решение, но я (как вы можете видеть) очень плохо разбираюсь в регулярных выражениях.
Прости! Совсем забыл. Теперь добавлены примеры!
Каков ваш ожидаемый результат здесь? Что вы хотите делать с информацией? Писать куда-нибудь в лог / таблицу? Что-то другое?
Конечным результатом будет фрейм данных со столбцами: дата, время, отправитель, сообщение.






Вот общее регулярное выражение и решение с использованием re.findall:
msg = "[19.09.17, 19:54:48] Marc: If the mean is not in the thousands, there's the problem
[19.09.17, 19:54:59] Joe: > mean(aging$Population)
[1] 1593.577\nIs what I get as solution"
results = re.findall(r"\[(\d{2}\.\d{2}\.\d{2}), (\d{2}:\d{2}:\d{2})\] ([^:]+): (.*?)(?=\[\d{2}\.\d{2}\.\d{2}, \d{2}:\d{2}:\d{2}\]|$)", msg, re.MULTILINE|re.DOTALL)
for item in results:
print "date: " + item[0]
print "time: " + item[1]
print "sender: " + item[2]
print "message: " + item[3]
date: 19.09.17
time: 19:54:48
sender: Marc
message: If the mean is not in the thousands, there's the problem
date: 19.09.17
time: 19:54:59
sender: Joe
message: > mean(aging$Population)
Шаблон, который кажется длинным и раздутым, просто соответствует структуре вашего ожидаемого сообщения WhatsApp. Следует отметить, что в шаблоне используются как многострочный режим, так и режим ТОЧКИ ВСЕ. Это необходимо для сообщений, которые могут занимать несколько строк. Шаблон прекращает использование данного сообщения, когда либо он видит начало следующего сообщения (в частности, временную метку), либо видит конец ввода.
Спасибо большое за помощь! Однако последнее сообщение не было полным, что и было той проблемой, с которой я сталкивался раньше. В нем нет второй и третьей строчки. Прямо сейчас он просто возвращает '> mean (ageing $ Population') и обрезает все, что следует. Даже если я использую что-то более простое, чем строка [1] ...
Я не уверен, что вижу проблему. Мой ответ работает для двух строк, но вы говорите, что он не работает для трех строк?
В вашем решении для многострочного сообщения оно выдает: message:> mean (ageing $ Population) Тем не менее, сообщение состояло из трех строк. «[1] 1593,577 - это то, что я получаю в качестве решения» там отсутствует. Извините, если я веду себя глупо, но когда я пробую его в своем блокноте, он также просто захватывает первую строку сообщения.
Установите демо и вставьте ссылку сюда.
Демонстрация: pyfiddle.io/fiddle/3c578619-d94a-4d40-82ab-b74ff06dab89/?i=t рут Проблема: соответствует только первой строке сообщения. Я не могу заставить его сохранить все строки в объекте результатов.
@Nickfis Я проверил вашу демонстрацию и не понимаю, в чем проблема. Если вы хотите вывести всю строку, просто используйте print(results[0]). Я что-то упустил?
Наверное, я плохо это формулирую. Извините за то, что отнял у вас так много времени, но проблема в том, что само сообщение состоит из нескольких строк. Я хочу сохранить все в одном сообщении. Прямо сейчас он выводит только '> mean (ageing $ Population)', но строки 2 и 3 этого сообщения: [1] 1593.577 Это то, что я получаю в качестве решения, не включены. Я также обновил демо, чтобы там было немного понятнее!
Пожалуйста, вставьте новую демонстрационную ссылку, и я посмотрю.
Та же ссылка! pyfiddle.io/fiddle/3c578619-d94a-4d40-82ab-b74ff06dab89/?i=t рут
Взяв указанное выше, чтобы соответствовать в случае многострочного, я только что обрезал регулярное выражение от Тима Бигелейзена
results = re.findall(r"\[(\d{2}\.\d{2}\.\d{2}), (\d{2}:\d{2}:\d{2})\] ([^:]+): (.*?)(?=\[\d{2}\.\d{2}\.\d{2}, \d{2}:\d{2}:\d{2}\])", msg, re.MULTILINE|re.DOTALL)
На этот вопрос сейчас нет ответа, если только читатель точно не знает, как выглядит ваш текст в WhatsApp (чего вы не должны предполагать). Пожалуйста, покажите нам примеры как однострочного сообщения WhatsApp, так и многострочного сообщения.