Синтаксический разбор текста по электронной почте
Я создаю веб-клиент электронной почты, используя С# asp.net.
Что сбивает с толку, так это то, что различные почтовые клиенты, кажется, добавляют оригинальный текст по-разному, когда отвечают по электронной почте.
Что мне было интересно, так это, если есть какой-то стандартизованный способ, чтобы устранить этот процесс?
Спасибо.
-Theo
Ответы
Ответ 1
Существует не стандартизованный способ, но разумная эвристика доставит вам хорошее расстояние.
Некоторые алгоритмы классифицируют строки на основе их начального символа (ов) и сравнивая текст с корпусом помеченного текста, получая статистическая вероятность для каждой строки: a) часть того же блока, что и следующая/предыдущая, и b) цитируемый текст, подпись, новый текст и т.д.
Было бы полезно попробовать некоторые из самых популярных почтовых клиентов и создать и сравнить некоторые примеры сообщений, чтобы узнать, что различия. Группы новостей Usenet также могут помочь вам создать разумный корпус сообщений для работы. HTML-сообщение электронной почты добавляет дополнительный уровень сложности, конечно, хотя большинство совместимых почтовых клиентов будут включать в себя также и соответствующий текст. Различные языки также вызывают проблемы, так как клиенты, которые могут анализировать "Павел писал:", могут упасть на "Pablo ha scritto:".
Ответ 2
Я думал:
public String cleanMsgBody(String oBody, out Boolean isReply)
{
isReply = false;
Regex rx1 = new Regex("\n-----");
Regex rx2 = new Regex("\n([^\n]+):([ \t\r\n\v\f]+)>");
Regex rx3 = new Regex("([0-9]+)/([0-9]+)/([0-9]+)([^\n]+)<([^\n]+)>");
String txtBody = oBody;
while (txtBody.Contains("\n\n")) txtBody = txtBody.Replace("\n\n", "\n");
while (new Regex("\n ").IsMatch(txtBody)) txtBody = (new Regex("\n ")).Replace(txtBody, "\n");
while (txtBody.Contains(" ")) txtBody = txtBody.Replace(" ", " ");
if (isReply = (isReply || rx1.IsMatch(txtBody)))
txtBody = rx1.Split(txtBody)[0]; // Maybe a loop through would be better
if (isReply = (isReply || rx2.IsMatch(txtBody)))
txtBody = rx2.Split(txtBody)[0]; // Maybe a loop through would be better
if (isReply = (isReply || rx3.IsMatch(txtBody)))
txtBody = rx3.Split(txtBody)[0]; // Maybe a loop through would be better
return txtBody;
}
Ответ 3
Не совсем, нет.
Оригинальный RFC для интернет-сообщения рассказывает о заголовке in-reply-to
, но не указывает формат тела.
Как вы обнаружили, разные клиенты добавляют оригинальный текст по-разному, подразумевая, что нет стандарта, в сочетании с тем, что пользователи будут делать что-то по-другому:
- Обычный текст, "богатый текст", HTML будет иметь другой способ разделения ответа от оригинала
- В Outlook я могу выбрать один из следующих вариантов при ответе на сообщение:
- Не включать
- Приложить оригинальное сообщение
- Включить исходный текст сообщения
- Включить и отменить исходный текст сообщения
- Префикс каждой строки исходного сообщения
- Кроме того, я часто отправляю и получаю ответы, в которых говорится "Ответы в строке", где мои комментарии смешиваются с исходным сообщением, поэтому исходное сообщение больше не существует в его первоначальной форме.
Ответ 4
Некоторые эвристики, которые вы можете попробовать,
- любое количество символов > -Посмотрите на "написал:" (будьте очень осторожны с этим)
Также вы можете попробовать связать поле Message ID с полем "В ответ на"
И, наконец, если вы не можете найти хорошую библиотеку для этого, пришло время начать этот проект. Больше не нужно разглашать электронные письма способом Cthulhu:)