J'essaie de comprendre comment analyser le texte d'un e-mail à partir de tout texte de réponse cité qu'il pourrait inclure. J'ai remarqué qu'en général, les clients de messagerie mettent un "À telle ou telle date telle ou telle date" ou préfixent les lignes avec un crochet angulaire. Malheureusement, tout le monde ne le fait pas. Quelqu'un at-il une idée sur la façon de détecter par programme le texte de réponse? J'utilise C # pour écrire cet analyseur.
c#
ruby
email
email-parsing
VanOrman
la source
la source
Réponses:
J'ai fait beaucoup plus de recherches à ce sujet et voici ce que j'ai trouvé. Il y a essentiellement deux situations dans lesquelles vous faites cela: lorsque vous avez le fil entier et quand vous ne le faites pas. Je vais le diviser en deux catégories:
Lorsque vous avez le fil:
Si vous disposez de toute la série d'e-mails, vous pouvez obtenir un niveau d'assurance très élevé que ce que vous supprimez est en fait du texte cité. Il y a deux façons de faire ça. Premièrement, vous pouvez utiliser l'ID de message, l'ID en réponse à et l'index de thread du message pour déterminer le message individuel, son parent et le thread auquel il appartient. Pour plus d' informations sur ce sujet , voir RFC822 , RFC2822 , cet article intéressant sur le filetage , ou cet article sur le filetage . Une fois que vous avez réassemblé le fil, vous pouvez ensuite supprimer le texte externe (comme les lignes À, De, CC, etc.) et vous avez terminé.
Si les messages avec lesquels vous travaillez n'ont pas d'en-têtes, vous pouvez également utiliser la correspondance de similarité pour déterminer quelles parties d'un e-mail sont le texte de réponse. Dans ce cas, vous êtes obligé de faire une correspondance de similitude pour déterminer le texte qui est répété. Dans ce cas, vous voudrez peut-être examiner un algorithme de distance de Levenshtein tel que celui-ci sur Code Project ou celui-ci .
Quoi qu'il en soit, si vous êtes intéressé par le processus de threading, consultez cet excellent PDF sur le réassemblage des fils de courrier électronique .
Lorsque vous n'avez pas le fil:
Si vous êtes bloqué avec un seul message du fil de discussion, vous devez essayer de deviner le devis. Dans ce cas, voici les différentes méthodes de cotation que j'ai vues:
Supprimez le texte à partir de là et vous avez terminé. L'inconvénient de l'un d'entre eux est qu'ils supposent tous que l'expéditeur a placé sa réponse au-dessus du texte cité et ne l'a pas entrelacée (comme c'était l'ancien style sur Internet). Si cela arrive, bonne chance. J'espère que cela aidera certains d'entre vous!
la source
Tout d'abord, c'est une tâche délicate.
Vous devez collecter les réponses typiques de différents clients de messagerie et préparer des expressions régulières correctes (ou autre) pour les analyser. J'ai recueilli des réponses d'Outlook, de Thunderbird, de Gmail, d'Apple Mail et de mail.ru.
J'utilise des expressions régulières pour analyser la réponse de la manière suivante: si l'expression ne correspond pas, j'essaie d'utiliser la suivante.
new Regex("From:\\s*" + Regex.Escape(_mail), RegexOptions.IgnoreCase); new Regex("<" + Regex.Escape(_mail) + ">", RegexOptions.IgnoreCase); new Regex(Regex.Escape(_mail) + "\\s+wrote:", RegexOptions.IgnoreCase); new Regex("\\n.*On.*(\\r\\n)?wrote:\\r\\n", RegexOptions.IgnoreCase | RegexOptions.Multiline); new Regex("-+original\\s+message-+\\s*$", RegexOptions.IgnoreCase); new Regex("from:\\s*$", RegexOptions.IgnoreCase);
Pour supprimer la citation à la fin:
new Regex("^>.*$", RegexOptions.IgnoreCase | RegexOptions.Multiline);
Voici ma petite collection de réponses aux tests (échantillons divisés par --- ):
From: [email protected] [mailto:[email protected]] Sent: Tuesday, January 13, 2009 1:27 PM ---- 2008/12/26 <[email protected]> > text ---- [email protected] wrote: > text ---- [email protected] wrote: text text ---- 2009/1/13 <[email protected]> > text ---- [email protected] wrote: text text ---- 2009/1/13 <[email protected]> > text > text ---- 2009/1/13 <[email protected]> > text > text ---- [email protected] wrote: > text > text <response here> ---- --- On Fri, 23/1/09, [email protected] <[email protected]> wrote: > text > text
Meilleures salutations, Oleg Yaroshevych
la source
Merci, Goleg, pour les regex! Vraiment aidé. Ce n'est pas C #, mais pour les googleurs, voici mon script d'analyse Ruby:
def extract_reply(text, address) regex_arr = [ Regexp.new("From:\s*" + Regexp.escape(address), Regexp::IGNORECASE), Regexp.new("<" + Regexp.escape(address) + ">", Regexp::IGNORECASE), Regexp.new(Regexp.escape(address) + "\s+wrote:", Regexp::IGNORECASE), Regexp.new("^.*On.*(\n)?wrote:$", Regexp::IGNORECASE), Regexp.new("-+original\s+message-+\s*$", Regexp::IGNORECASE), Regexp.new("from:\s*$", Regexp::IGNORECASE) ] text_length = text.length #calculates the matching regex closest to top of page index = regex_arr.inject(text_length) do |min, regex| [(text.index(regex) || text_length), min].min end text[0, index].strip end
Cela a plutôt bien fonctionné jusqu'à présent.
la source
Le moyen de loin le plus simple de le faire est de placer un marqueur dans votre contenu, tel que:
--- Veuillez répondre au-dessus de cette ligne ---
Comme vous l'avez sans doute remarqué, l'analyse du texte cité n'est pas une tâche triviale car différents clients de messagerie citent le texte de différentes manières. Pour résoudre correctement ce problème, vous devez prendre en compte et tester chaque client de messagerie.
Facebook peut le faire, mais à moins que votre projet n'ait un gros budget, vous ne pouvez probablement pas.
Oleg a résolu le problème en utilisant des expressions régulières pour trouver le texte "Le 13 juillet 2012, à 13:09, xxx a écrit:". Cependant, si l'utilisateur supprime ce texte ou répond en bas de l'e-mail, comme le font de nombreuses personnes, cette solution ne fonctionnera pas.
De même, si le client de messagerie utilise une chaîne de date différente ou n'inclut pas de chaîne de date, l'expression régulière échouera.
la source
-- Please reply above this line. DO NOT REMOVE IT! --
. De plus, ce que j'ai constaté, c'est que cela ne fonctionnera pas toujours puisque certains clients de messagerie ajoutent unexxx wrote on <datetime>:
ligne avant le devis entier et donc avant cette ligne. Cette ligne peut être analysée avec regex, mais elle peut être dans différentes langues et dans un format différent puisque les clients de messagerie diffèrent.Il n'y a pas d'indicateur universel de réponse dans un e-mail. Le mieux que vous puissiez faire est d'essayer d'attraper les plus courants et d'analyser les nouveaux modèles au fur et à mesure que vous les rencontrez.
Gardez à l'esprit que certaines personnes insèrent des réponses dans le texte cité (mon patron par exemple répond aux questions sur la même ligne que je leur ai posé) donc quoi que vous fassiez, vous risquez de perdre des informations que vous auriez aimé conserver.
la source
Voici ma version C # du code Ruby de @ hurshagrawal. Je ne connais pas très bien Ruby donc ça pourrait être faux, mais je pense que j'ai bien compris.
public string ExtractReply(string text, string address) { var regexes = new List<Regex>() { new Regex("From:\\s*" + Regex.Escape(address), RegexOptions.IgnoreCase), new Regex("<" + Regex.Escape(address) + ">", RegexOptions.IgnoreCase), new Regex(Regex.Escape(address) + "\\s+wrote:", RegexOptions.IgnoreCase), new Regex("\\n.*On.*(\\r\\n)?wrote:\\r\\n", RegexOptions.IgnoreCase | RegexOptions.Multiline), new Regex("-+original\\s+message-+\\s*$", RegexOptions.IgnoreCase), new Regex("from:\\s*$", RegexOptions.IgnoreCase), new Regex("^>.*$", RegexOptions.IgnoreCase | RegexOptions.Multiline) }; var index = text.Length; foreach(var regex in regexes){ var match = regex.Match(text); if(match.Success && match.Index < index) index = match.Index; } return text.Substring(0, index).Trim(); }
la source
Si vous contrôlez le message d'origine (par exemple, les notifications d'une application Web), vous pouvez mettre en place un en-tête distinct et identifiable et l'utiliser comme délimiteur pour le message d'origine.
la source
C'est une bonne solution. Je l'ai trouvé après avoir cherché si longtemps.
Un ajout, comme mentionné ci-dessus, c'est casse, donc les expressions ci-dessus n'ont pas analysé correctement mes réponses gmail et outlook (2010), pour lesquelles j'ai ajouté les deux expressions régulières suivantes. Faites-moi savoir pour tout problème.
//Works for Gmail new Regex("\\n.*On.*<(\\r\\n)?" + Regex.Escape(address) + "(\\r\\n)?>", RegexOptions.IgnoreCase), //Works for Outlook 2010 new Regex("From:.*" + Regex.Escape(address), RegexOptions.IgnoreCase),
À votre santé
la source
C'est un ancien message, cependant, je ne sais pas si vous savez que github a une librairie Ruby extrayant la réponse. Si vous utilisez .NET, j'en ai un .NET sur https://github.com/EricJWHuang/EmailReplyParser
la source
Si vous utilisez l'API de SigParser.com , il vous donnera un tableau de tous les e-mails éclatés dans une chaîne de réponse à partir d'une seule chaîne de texte d'e-mail. Donc, s'il y a 10 e-mails, vous obtiendrez le texte des 10 e-mails.
Vous pouvez consulter les spécifications détaillées de l'API ici.
https://api.sigparser.com/
la source