Saya mencoba mencari cara untuk mengurai teks email dari teks balasan kutipan yang mungkin disertakan. Saya perhatikan bahwa biasanya klien email akan meletakkan "Pada tanggal ini dan itu menulis ini dan itu" atau mengawali baris dengan tanda kurung siku. Sayangnya, tidak semua orang melakukan ini. Adakah yang tahu tentang cara mendeteksi teks balasan secara terprogram? Saya menggunakan C # untuk menulis parser ini.
c#
ruby
email
email-parsing
VanOrman
sumber
sumber
Jawaban:
Saya melakukan lebih banyak pencarian tentang ini dan inilah yang saya temukan. Pada dasarnya ada dua situasi saat Anda melakukan ini: saat Anda memiliki seluruh utas dan saat tidak. Saya akan memecahnya menjadi dua kategori itu:
Jika Anda memiliki utas:
Jika Anda memiliki seluruh rangkaian email, Anda dapat mencapai tingkat jaminan yang sangat tinggi bahwa apa yang Anda hapus sebenarnya adalah teks kutipan. Ada dua cara untuk melakukannya. Pertama, Anda dapat menggunakan Message-ID, In-Reply-To ID, dan Thread-Index untuk menentukan pesan individual, induknya, dan utasnya. Untuk informasi lebih lanjut tentang ini, lihat RFC822 , RFC2822 , artikel menarik tentang threading ini , atau artikel tentang threading ini . Setelah Anda memasang kembali utas, Anda dapat menghapus teks eksternal (seperti baris Kepada, Dari, CC, dll ...) dan selesai.
Jika pesan yang Anda kerjakan tidak memiliki header, Anda juga dapat menggunakan pencocokan kesamaan untuk menentukan bagian email mana yang merupakan teks balasan. Dalam hal ini Anda terjebak dengan melakukan pencocokan kesamaan untuk menentukan teks yang diulang. Dalam hal ini Anda mungkin ingin melihat algoritma Jarak Levenshtein seperti ini di Proyek Kode atau yang satu ini .
Apa pun yang terjadi, jika Anda tertarik dengan proses threading, lihat PDF hebat ini tentang memasang kembali utas email .
Jika Anda tidak memiliki utas:
Jika Anda terjebak dengan hanya satu pesan dari utas, Anda harus mencoba menebak apa kutipannya. Dalam hal ini, berikut adalah metode kutipan berbeda yang telah saya lihat:
Hapus teks dari sana ke bawah dan Anda selesai. Kelemahan dari semua ini adalah bahwa mereka semua berasumsi bahwa pengirim meletakkan balasan mereka di atas teks kutipan dan tidak menyisipkannya (seperti gaya lama di internet). Jika itu terjadi, semoga berhasil. Saya harap ini membantu beberapa dari Anda di luar sana!
sumber
Pertama-tama, ini adalah tugas yang sulit.
Anda harus mengumpulkan tanggapan umum dari klien email yang berbeda dan menyiapkan ekspresi reguler yang benar (atau apa pun) untuk menguraikannya. Saya telah mengumpulkan tanggapan dari outlook, thunderbird, gmail, apple mail dan mail.ru.
Saya menggunakan ekspresi reguler untuk mengurai respons dengan cara berikut: jika ekspresi tidak cocok, saya mencoba menggunakan yang berikutnya.
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);
Untuk menghapus kutipan pada akhirnya:
new Regex("^>.*$", RegexOptions.IgnoreCase | RegexOptions.Multiline);
Berikut adalah kumpulan kecil tanggapan pengujian saya (sampel dibagi dengan --- ):
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
Salam Hormat, Oleg Yaroshevych
sumber
Terima kasih, Goleg, untuk regexnya! Sangat membantu. Ini bukan C #, tapi untuk googler di luar sana, inilah skrip parsing Ruby saya:
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
Sejauh ini, ini bekerja dengan cukup baik.
sumber
Sejauh ini, cara termudah untuk melakukannya adalah dengan menempatkan penanda di konten Anda, seperti:
--- Harap balas di atas baris ini ---
Seperti yang sudah Anda ketahui, mengurai kutipan teks bukanlah tugas yang mudah karena klien email yang berbeda mengutip teks dengan cara yang berbeda. Untuk mengatasi masalah ini dengan benar, Anda perlu memperhitungkan dan menguji di setiap klien email.
Facebook dapat melakukan ini, tetapi jika proyek Anda memiliki anggaran yang besar, Anda mungkin tidak dapat melakukannya.
Oleg telah memecahkan masalah menggunakan regex untuk menemukan teks "Pada 13 Jul 2012, pada 13:09, xxx menulis:". Namun, jika pengguna menghapus teks ini, atau membalas di bagian bawah email, seperti yang dilakukan banyak orang, solusi ini tidak akan berfungsi.
Begitu juga jika klien email menggunakan string tanggal yang berbeda, atau tidak menyertakan string tanggal, regex akan gagal.
sumber
-- Please reply above this line. DO NOT REMOVE IT! --
. Juga, Apa yang saya alami adalah bahwa itu tidak selalu berhasil karena beberapa klien email menambahkanxxx wrote on <datetime>:
baris sebelum seluruh kutipan dan sebelum baris itu. Baris ini dapat diurai dengan ekspresi reguler, namun mungkin dalam bahasa yang berbeda dan dalam format yang berbeda karena klien email berbeda.Tidak ada indikator universal balasan dalam email. Hal terbaik yang dapat Anda lakukan adalah mencoba menangkap pola paling umum dan mengurai baru saat Anda menemukannya.
Ingatlah bahwa beberapa orang memasukkan balasan ke dalam teks kutipan (Bos saya misalnya menjawab pertanyaan pada baris yang sama seperti yang saya tanyakan) jadi apa pun yang Anda lakukan, Anda mungkin kehilangan beberapa informasi yang ingin Anda simpan.
sumber
Ini adalah kode Ruby versi C # saya dari @ hurshagrawal. Saya tidak terlalu mengenal Ruby sehingga bisa saja tidak aktif, tapi saya pikir saya sudah benar.
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(); }
sumber
Jika Anda mengontrol pesan asli (mis. Pemberitahuan dari aplikasi web), Anda dapat menempatkan header yang berbeda dan dapat diidentifikasi, dan menggunakannya sebagai pembatas untuk posting asli.
sumber
Ini adalah solusi yang bagus. Menemukannya setelah lama mencari.
Satu tambahan, seperti yang disebutkan di atas, ini adalah kasus bijaksana, jadi ekspresi di atas tidak mengurai dengan benar tanggapan gmail dan pandangan (2010) saya, yang saya tambahkan dua Regex berikut (s). Beri tahu saya jika ada masalah.
//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),
Bersulang
sumber
Ini adalah posting lama, namun, tidak yakin apakah Anda tahu github memiliki lib Ruby yang mengekstrak balasannya. Jika Anda menggunakan .NET, saya memiliki .NET di https://github.com/EricJWHuang/EmailReplyParser
sumber
Jika Anda menggunakan API SigParser.com , ini akan memberi Anda array dari semua email yang dipecah dalam rantai balasan dari satu string teks email. Jadi jika ada 10 email, Anda akan mendapatkan teks untuk 10 email tersebut.
Anda dapat melihat spesifikasi API mendetail di sini.
https://api.sigparser.com/
sumber