2010-03-05 6 views
13

Sto analizzando le email. Quando visualizzo una risposta a un'e-mail, vorrei rimuovere il testo citato in modo che possa aggiungere il testo all'email precedente (anche se è una risposta).Come rimuovere il testo citato da una e-mail e mostrare solo il nuovo testo

In genere, si vedrà questo:

prima e-mail (inizio della conversazione)

This is the first email 

seconda e-mail (risposta alla prima)

This is the second email 

Tim said: 
This is the first email 

L'uscita di questo sarebbe "Questa è solo la seconda email". Sebbene diversi client di posta elettronica citino il testo in modo diverso, se ci fosse in qualche modo di ottenere solo il nuovo testo di posta elettronica, sarebbe anche accettabile.

risposta

2

Quando le e-mail precedenti sono memorizzate sul disco, o disponibili come di consueto, è possibile controllare tutte le e-mail, inviare da un ricevitore specifico per determinare, che è il testo di risposta.

Si potrebbe anche provare a determinare il carattere di citazione, controllando il primo carattere delle ultime righe. Normalmente le ultime righe iniziano sempre con lo stesso carattere.

Quando le ultime 2 righe iniziano con un carattere ifferent, puoi provare le prime righe, perché a volte la risposta viene aggiunta alla fine del testo.

Se è stato rilevato questo carattere, è possibile eliminare le ultime righe che iniziano con questo carattere finché non viene rilevata una riga vuota o una riga che inizia con un altro carattere.

non testati ed è più simile pseudo codice

String[] lines; 

    // Check the size of the array first, length > 2 
    char startingChar = lines[lines.length - 1].charAt(0); 
    int foundCounter = 0; 
    for (int i = lines.length - 2; i >=0; --i) { 
     String line = lines[i]; 

     // Check line size > 0 
     if(startingChar == line.charAt(0)){ 
      ++foundCounter; 
     } 
    } 

    final int YOUR_DECISION = 2; // You can decide 
    if(foundCounter > YOUR_DECISION){ 
     deleteLastLinesHere(startingChar, foundCounter); 
    } 
+1

'char startingChar = lines [lines.length - 1];' non verrà compilato. Intendevi 'char startingChar = lines [lines.length - 1] .charAt (0);'? – sfussenegger

+1

sì, mi dispiace. Come ho detto, questo è più simile a pseudo codice;). I aggiornerà la risposta –

1

Da osservare il comportamento di Gmail a questo proposito ho osservato la loro strategia:

  1. scrivere la totale 2 ° di posta.
  2. aggiungere testo come: On [timestamp], [Nome E-mail del mittente] < [prima e-mail del mittente Indirizzo e-mail]> ha scritto:
  3. Aggiungere il completo prima e-mail. a. Se la tua e-mail è in formato testo, allora premi '>' prima di ogni riga della prima e-mail. b. Se è in HTML, Gmail assegna un margine sinistro come:

    border-left: 1px solid #CCC; margine: 0px 0px 0px 0.8ex; padding-left: 1ex; foglio di stile utente blockquote

    e quindi aggiunge il testo della prima email.

È possibile eseguire il reverse engineering quando si analizzano le e-mail dall'indirizzo Gmail. Non ho esaminato altri client, ma dovrebbero avere lo stesso comportamento.

1

Avrete capito quasi subito con un paio di righe di codice:

String newMessage = ""; 
for (String line : emailLines) { 
    if (!line.matches("^[>].*")) { 
    newMessage = newMessage.concat(line); 
    } 
} 

Se necessario, è possibile aggiungere altri controlli regex per i client di posta elettronica che lasciano firme diverse testo citato.

+0

Mi piace l'approccio semplicistico. –

12

utilizzare la seguente espressione regolare (s) in modo che corrisponda l'iniziativa per il testo citato (l'ultima è quella che conta):

/** general spacers for time and date */ 
    private static final String spacers = "[\\s,/\\.\\-]"; 

    /** matches times */ 
    private static final String timePattern = "(?:[0-2])?[0-9]:[0-5][0-9](?::[0-5][0-9])?(?:(?:\\s)?[AP]M)?"; 

    /** matches day of the week */ 
    private static final String dayPattern = "(?:(?:Mon(?:day)?)|(?:Tue(?:sday)?)|(?:Wed(?:nesday)?)|(?:Thu(?:rsday)?)|(?:Fri(?:day)?)|(?:Sat(?:urday)?)|(?:Sun(?:day)?))"; 

    /** matches day of the month (number and st, nd, rd, th) */ 
    private static final String dayOfMonthPattern = "[0-3]?[0-9]" + spacers + "*(?:(?:th)|(?:st)|(?:nd)|(?:rd))?"; 

    /** matches months (numeric and text) */ 
    private static final String monthPattern = "(?:(?:Jan(?:uary)?)|(?:Feb(?:uary)?)|(?:Mar(?:ch)?)|(?:Apr(?:il)?)|(?:May)|(?:Jun(?:e)?)|(?:Jul(?:y)?)" + 
               "|(?:Aug(?:ust)?)|(?:Sep(?:tember)?)|(?:Oct(?:ober)?)|(?:Nov(?:ember)?)|(?:Dec(?:ember)?)|(?:[0-1]?[0-9]))"; 

    /** matches years (only 1000's and 2000's, because we are matching emails) */ 
    private static final String yearPattern = "(?:[1-2]?[0-9])[0-9][0-9]"; 

    /** matches a full date */ 
    private static final String datePattern  = "(?:" + dayPattern + spacers + "+)?(?:(?:" + dayOfMonthPattern + spacers + "+" + monthPattern + ")|" + 
               "(?:" + monthPattern + spacers + "+" + dayOfMonthPattern + "))" + 
               spacers + "+" + yearPattern; 

    /** matches a date and time combo (in either order) */ 
    private static final String dateTimePattern = "(?:" + datePattern + "[\\s,]*(?:(?:at)|(?:@))?\\s*" + timePattern + ")|" + 
               "(?:" + timePattern + "[\\s,]*(?:on)?\\s*"+ datePattern + ")"; 

    /** matches a leading line such as 
    * ----Original Message---- 
    * or simply 
    * ------------------------ 
    */ 
    private static final String leadInLine = "-+\\s*(?:Original(?:\\sMessage)?)?\\s*-+\n"; 

    /** matches a header line indicating the date */ 
    private static final String dateLine = "(?:(?:date)|(?:sent)|(?:time)):\\s*"+ dateTimePattern + ".*\n"; 

    /** matches a subject or address line */ 
    private static final String subjectOrAddressLine = "((?:from)|(?:subject)|(?:b?cc)|(?:to))|:.*\n"; 

    /** matches gmail style quoted text beginning, i.e. 
    * On Mon Jun 7, 2010 at 8:50 PM, Simon wrote: 
    */ 
    private static final String gmailQuotedTextBeginning = "(On\\s+" + dateTimePattern + ".*wrote:\n)"; 


    /** matches the start of a quoted section of an email */ 
    private static final Pattern QUOTED_TEXT_BEGINNING = Pattern.compile("(?i)(?:(?:" + leadInLine + ")?" + 
                     "(?:(?:" +subjectOrAddressLine + ")|(?:" + dateLine + ")){2,6})|(?:" + 
                     gmailQuotedTextBeginning + ")" 
                    ); 

So che in un certo senso questo è eccessivo (e potrebbe sii lento!) ma funziona piuttosto bene. Per favore fatemi sapere se trovate qualcosa che non corrisponde a questo in modo da poterlo migliorare!

+1

Qual è il significato di {2,6} nel QUOTED_TEXT_BEGINNING? Puoi fare un esempio che corrisponderebbe? – Divij

+1

@Divij si richiede che vi siano almeno 2 e non più di 6 riga dal set di: soggetto, a, da, bcc, cc, data. Un minimo sarà simile al soggetto e, al massimo, tutte 6. Sembravano verificarsi in qualsiasi ordine, così ho mantenuto l'ordine sciolto, ma ha voluto vincolati per motivi di qualità e prestazioni. – smurthas

+0

Grazie per la tua risposta, è molto pieno per noi. ma, questo modello non o per la riga seguente è "On 16-09-2014, Indie Servizi di prova ha scritto:" si prega di dare una soluzione al più presto possibile –

2

RegEx funziona bene, tranne che corrisponda testo che inizia da soggetto e ignora tutto ciò che va prima di "Oggetto"

Text 
-------- Original Message -------- 
<TABLE border="0" cellpadding="0" cellspacing="0"> 
    <TBODY> 
    <TR> 
     <TH align="right" valign="baseline"> 
     // the matcher starts working from here 
5

Partenza il brevetto di Google su questo: http://www.google.com/patents/US7222299

In sintesi si hash porzioni di il testo (presumibilmente qualcosa come le frasi) e quindi cercare le corrispondenze negli hash nei messaggi precedenti. Super veloce e probabilmente lo usano anche come input per l'algoritmo di threading. Che bella idea!