Сопоставление сообщений из журнала WhatsApp в Python

Я хотел бы извлечь все шаблоны, соответствующие сообщению в 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, поэтому даты немного другие. Также я закончил на, и], чтобы случайно не получить совпадения из сообщений.

Я хотел бы сделать то же самое с шаблоном сообщения, заканчившись на [, который обычно является началом следующей строки (но может быть не очень надежным, если его можно найти в сообщении на новой строке).

Вероятно, есть более простое решение, но я (как вы можете видеть) очень плохо разбираюсь в регулярных выражениях.

На этот вопрос сейчас нет ответа, если только читатель точно не знает, как выглядит ваш текст в WhatsApp (чего вы не должны предполагать). Пожалуйста, покажите нам примеры как однострочного сообщения WhatsApp, так и многострочного сообщения.

Tim Biegeleisen 09.12.2018 14:52

Прости! Совсем забыл. Теперь добавлены примеры!

Nickfis 09.12.2018 16:13

Каков ваш ожидаемый результат здесь? Что вы хотите делать с информацией? Писать куда-нибудь в лог / таблицу? Что-то другое?

Tim Biegeleisen 09.12.2018 16:18

Конечным результатом будет фрейм данных со столбцами: дата, время, отправитель, сообщение.

Nickfis 09.12.2018 18:32
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
277
2

Ответы 2

Вот общее регулярное выражение и решение с использованием 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] ...

Nickfis 09.12.2018 18:31

Я не уверен, что вижу проблему. Мой ответ работает для двух строк, но вы говорите, что он не работает для трех строк?

Tim Biegeleisen 10.12.2018 00:30

В вашем решении для многострочного сообщения оно выдает: message:> mean (ageing $ Population) Тем не менее, сообщение состояло из трех строк. «[1] 1593,577 - это то, что я получаю в качестве решения» там отсутствует. Извините, если я веду себя глупо, но когда я пробую его в своем блокноте, он также просто захватывает первую строку сообщения.

Nickfis 10.12.2018 10:42

Установите демо и вставьте ссылку сюда.

Tim Biegeleisen 10.12.2018 10:59

Демонстрация: pyfiddle.io/fiddle/3c578619-d94a-4d40-82ab-b74ff06dab89/?i=t‌ рут Проблема: соответствует только первой строке сообщения. Я не могу заставить его сохранить все строки в объекте результатов.

Nickfis 10.12.2018 19:30

@Nickfis Я проверил вашу демонстрацию и не понимаю, в чем проблема. Если вы хотите вывести всю строку, просто используйте print(results[0]). Я что-то упустил?

Tim Biegeleisen 11.12.2018 06:06

Наверное, я плохо это формулирую. Извините за то, что отнял у вас так много времени, но проблема в том, что само сообщение состоит из нескольких строк. Я хочу сохранить все в одном сообщении. Прямо сейчас он выводит только '> mean (ageing $ Population)', но строки 2 и 3 этого сообщения: [1] 1593.577 Это то, что я получаю в качестве решения, не включены. Я также обновил демо, чтобы там было немного понятнее!

Nickfis 11.12.2018 10:38

Пожалуйста, вставьте новую демонстрационную ссылку, и я посмотрю.

Tim Biegeleisen 11.12.2018 11:25

Та же ссылка! pyfiddle.io/fiddle/3c578619-d94a-4d40-82ab-b74ff06dab89/?i=t‌ рут

Nickfis 11.12.2018 11:51

Взяв указанное выше, чтобы соответствовать в случае многострочного, я только что обрезал регулярное выражение от Тима Бигелейзена

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)

Другие вопросы по теме