94 votes

Analyse du contenu du courriel à partir d'une réponse citée

J'essaie de trouver comment analyser le texte d'un courriel à partir de tout texte de réponse cité qu'il pourrait inclure. J'ai remarqué que les clients de messagerie mettent généralement un "A telle date, untel a écrit" ou préfixent les lignes par un crochet. Malheureusement, tout le monde ne fait pas cela. Quelqu'un a-t-il une idée de la manière de détecter par programme le texte de la réponse ? J'utilise C# pour écrire ce parseur.

2 votes

Avez-vous eu de la chance avec ça ? Je cherche à faire exactement la même chose.

0 votes

Une solution finale avec un code source complet et un exemple de travail à ce sujet ?

0 votes

Quotequail fait cela en Python

61voto

VanOrman Points 2149

J'ai fait beaucoup de recherches sur 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 lorsque vous ne l'avez pas. Je vais les répartir dans ces deux catégories :

Quand vous aurez le fil :

Si vous disposez de l'ensemble de la série d'e-mails, vous pouvez obtenir un niveau de garantie très élevé que ce que vous supprimez est effectivement du texte cité. Il y a deux façons de procéder. La première consiste à utiliser l'ID du message, l'ID In-Reply-To et l'index du fil de discussion pour déterminer le message individuel, son parent et le fil de discussion auquel il appartient. Pour plus d'informations à ce sujet, voir RFC822 , RFC2822 , cet article intéressant sur l'enfilage o cet article sur l'enfilage . Une fois que vous avez réassemblé le fil, vous pouvez alors supprimer le texte externe (comme les lignes To, From, CC, etc...) et vous avez terminé.

Si les messages sur lesquels vous travaillez ne comportent pas d'en-têtes, vous pouvez également utiliser la correspondance par similarité pour déterminer quelles parties d'un e-mail constituent le texte de la réponse. Dans ce cas, vous êtes contraint de procéder à une comparaison par similarité pour déterminer le texte qui est répété. Dans ce cas, vous pouvez envisager d'utiliser une méthode de comparaison par similarité. Algorithme de distance de Levenshtein comme celui-ci sur Code Project o celui-ci .

Quoi qu'il en soit, si vous êtes intéressé par le processus d'enfilage, jetez un œil à cet excellent PDF sur le réassemblage des fils de courriel .

Quand vous n'avez pas le fil :

Si vous ne disposez que d'un seul message du fil de discussion, vous devrez essayer de deviner de quelle citation il s'agit. Dans ce cas, voici les différentes méthodes de citation que j'ai vues :

  1. une ligne (comme dans les perspectives).
  2. Angle Brackets
  3. "---Original Message---"
  4. "Un tel jour, un tel a écrit :"

Enlevez le texte de là en bas et vous avez terminé. L'inconvénient de toutes ces méthodes est qu'elles supposent toutes que l'expéditeur a placé sa réponse au-dessus du texte cité et ne l'a pas intercalé (comme c'était l'habitude sur Internet). Si c'est le cas, bonne chance. J'espère que cela aidera certains d'entre vous !

36voto

Oleg Yaroshevych Points 615

Tout d'abord, il s'agit d'une tâche délicate.

Vous devez collecter les réponses types de différents clients de messagerie et préparer des expressions régulières correctes (ou autre) pour les analyser. J'ai collecté des réponses de outlook, thunderbird, Gmail, Apple mail, et mail.ru.

J'utilise des expressions régulières pour analyser les réponses de la manière suivante : si une expression ne correspond pas, j'essaie d'utiliser l'expression 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: test@test.com [mailto:test@test.com] 
Sent: Tuesday, January 13, 2009 1:27 PM
----
2008/12/26 <test@test.com>

>  text
----
test@test.com wrote:
> text
----
      test@test.com wrote:         text
text
----
2009/1/13 <test@test.com>

>  text
----
 test@test.com wrote:         text
 text
----
2009/1/13 <test@test.com>

> text
> text
----
2009/1/13 <test@test.com>

> text
> text
----
test@test.com wrote:
> text
> text
<response here>
----
--- On Fri, 23/1/09, test@test.com <test@test.com> wrote:

> text
> text

0 votes

Que faire si je ne connais pas l'adresse électronique ?

0 votes

@Shyamal-Parikh cela ne fonctionnera pas pour les courriels en html, mais généralement un message en clair est également inclus dans les messages électroniques.

26voto

hurshagrawal Points 376

Merci, Goleg, pour les regex ! Ça m'a vraiment aidé. Ce n'est pas du C#, mais pour les googleurs, voici mon analyse Ruby de script :

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

Ça a plutôt bien marché jusqu'à présent.

1 votes

Vous devriez faire une question ruby et y répondre avec ce code au lieu de le poster sur une question c#.

6 votes

@Matthieu, ce n'est pas seulement une question de C#, mais une question d'email et d'email-parsing. totalement pertinent à mon avis.

0 votes

@Trent : le tag C# devrait être abandonné alors.

13voto

superluminary Points 5496

La façon la plus simple de le faire est de placer un marqueur dans votre contenu, par exemple :

--- 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 les différents clients de messagerie citent le texte de différentes manières. Pour résoudre ce problème correctement, vous devez prendre en compte et tester chaque client de messagerie.

Facebook peut le faire, mais à moins que votre projet ne dispose d'un gros budget, vous ne pouvez probablement pas le faire.

Oleg a résolu le problème en utilisant des regex 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'email, comme beaucoup de personnes le font, 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, la regex échouera.

0 votes

Cette approche échoue avec les réponses aux réponses, à moins que vous ne mettiez cette ligne à chaque réponse.

1 votes

Oui, cela présente des inconvénients. Si l'utilisateur supprime la réponse au-dessus de la chaîne de caractères, votre réponse échouera. Dans ce cas, j'envoie à l'utilisateur un message direct lui indiquant que son message a échoué, avec un lien pour répondre via l'application Web. La plupart des utilisateurs semblent être en mesure de l'utiliser sans trop de problèmes.

0 votes

Cela devrait être la réponse acceptée. Toutefois, j'ajouterais l'information selon laquelle la réponse ne sera pas acceptée si la ligne est supprimée.

7voto

3Doubloons Points 1099

Il n'existe pas d'indicateur universel de réponse dans un e-mail. Le mieux que vous puissiez faire est d'essayer de repérer 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 à l'intérieur du texte cité (mon patron, par exemple, répond aux questions sur la même ligne que celle où je les ai posées) ; par conséquent, quoi que vous fassiez, vous risquez de perdre certaines informations que vous auriez voulu conserver.

0 votes

Gmail le fait... du moins il semble le faire. Si je me souviens bien, il y a un identifiant de fil qui ne change pas entre l'original et les réponses...

0 votes

Gmail peut ajouter des '>' comme le font d'autres clients de messagerie, mais ce n'est pas une norme de messagerie et vous ne pouvez pas compter dessus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X