उद्धृत उत्तर से ईमेल सामग्री को पार्स करें


86

मैं यह पता लगाने की कोशिश कर रहा हूं कि किसी भी उद्धृत उत्तर पाठ से किसी ईमेल के पाठ को पार्स कैसे किया जा सकता है। मैंने देखा है कि आमतौर पर ईमेल क्लाइंट एक "ऐसी और इस तरह की तारीख पर लिखा होगा" और कोण कोष्ठक के साथ लाइनों को उपसर्ग करते हैं। दुर्भाग्य से, हर कोई ऐसा नहीं करता है। क्या किसी के पास प्रोग्राम टेक्स्ट का पता लगाने के तरीके पर कोई विचार है? मैं इस पार्सर को लिखने के लिए C # का उपयोग कर रहा हूं।


2
क्या आपको इससे कोई मतलब था? मैं ठीक यही काम करना चाह रहा हूं।
steve_c

पूर्ण स्रोत कोड नमूने के साथ कोई अंतिम समाधान इसके बारे में काम कर रहा है?
किकेनेट

पायक्विले पायथन में यह करता है
फिल्पेरो

किसी को भी इसके php संस्करण के लिए मदद कर सकते हैं?
user4271704

जवाबों:


60

मैंने इस पर और अधिक खोज की और यहाँ जो मैंने पाया है। मूल रूप से दो स्थितियां हैं जिनके तहत आप यह कर रहे हैं: जब आपके पास पूरा धागा है और जब आप नहीं करते हैं। मैं इसे उन दो श्रेणियों में तोड़ दूंगा:

जब आपके पास धागा हो:

यदि आपके पास ईमेल की पूरी श्रृंखला है, तो आप बहुत उच्च स्तर का आश्वासन प्राप्त कर सकते हैं कि आप जो हटा रहे हैं वह वास्तव में उद्धृत पाठ है। इसे करने के दो तरीके हैं। एक, आप व्यक्तिगत संदेश को निर्धारित करने के लिए संदेश के संदेश-आईडी, इन-रिप्लाई-टू आईडी, और थ्रेड-इंडेक्स का उपयोग कर सकते हैं, यह माता-पिता है, और यह जिस धागे से संबंधित है। इस बारे में अधिक जानकारी के लिए, RFC822 , RFC2822 , थ्रेडिंग का यह दिलचस्प लेख या थ्रेडिंग पर यह लेख देखें । एक बार जब आपने थ्रेड को फिर से इकट्ठा कर लिया है, तो आप बाहरी पाठ (जैसे कि, से, सीसी, आदि ... लाइनों) को हटा सकते हैं और आपका काम पूरा हो जाएगा।

यदि आप जिन संदेशों के साथ काम कर रहे हैं उनमें हेडर नहीं हैं, तो आप यह निर्धारित करने के लिए कि मेल के कौन से हिस्से उत्तर पाठ हैं, यह निर्धारित करने के लिए समानता मिलान का भी उपयोग कर सकते हैं। इस मामले में आप दोहराए गए पाठ को निर्धारित करने के लिए समानता मिलान करने के साथ फंस गए हैं। इस मामले में आप कोड प्रोजेक्ट या इस एक जैसे लेवेंसहाइट डिस्टेंस एल्गोरिथ्म में देखना चाहते हैं ।

इससे कोई फर्क नहीं पड़ता कि, यदि आप थ्रेडिंग प्रक्रिया में रुचि रखते हैं, तो ईमेल थ्रेड्स को पुनः प्राप्त करने वाले इस महान पीडीएफ को देखें

जब आपके पास धागा न हो:

यदि आप थ्रेड से केवल एक संदेश के साथ अटक गए हैं, तो आप यह अनुमान लगाने की कोशिश कर रहे हैं कि बोली क्या है। उस मामले में, यहाँ मैंने देखे गए अलग-अलग उद्धरण तरीके दिए हैं:

  1. एक लाइन (जैसा कि आउटलुक में देखा गया है)।
  2. कोण कोष्ठक
  3. "---वास्तविक सन्देश---"
  4. "इस तरह के और इस तरह के दिन, इतने पर लिखे गए:"

पाठ को वहां से हटा दें और आपका काम हो गया। इनमें से किसी के लिए नकारात्मक पक्ष यह है कि वे सभी मानते हैं कि प्रेषक ने अपना उत्तर उद्धृत पाठ के ऊपर रखा था और इसे इंटरलेव नहीं किया था (जैसा कि इंटरनेट पर पुरानी शैली थी)। यदि ऐसा होता है, तो सौभाग्य। मुझे आशा है कि यह आप में से कुछ को वहां से बाहर निकालने में मदद करता है!


32

सबसे पहले, यह एक मुश्किल काम है।

आपको अलग-अलग ई-मेल क्लाइंट से विशिष्ट प्रतिक्रियाएं एकत्र करनी चाहिए और उन्हें पार्स करने के लिए सही नियमित भाव (या जो भी) तैयार करना चाहिए। मैंने आउटलुक, थंडरबर्ड, जीमेल, ऐप्पल मेल और mail.ru से प्रतिक्रियाएं एकत्र की हैं।

मैं निम्नलिखित तरीके से प्रतिक्रिया को पार्स करने के लिए नियमित अभिव्यक्ति का उपयोग कर रहा हूं: यदि अभिव्यक्ति का मिलान नहीं हुआ, तो मैं अगले एक का उपयोग करने का प्रयास करता हूं।

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);

अंत में उद्धरण हटाने के लिए:

new Regex("^>.*$", RegexOptions.IgnoreCase | RegexOptions.Multiline);

यहाँ परीक्षण प्रतिक्रियाओं का मेरा छोटा सा संग्रह है ( --- द्वारा विभाजित नमूने ):

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

सादर, ओलेग यारोशेविक


यदि मुझे ईमेल पता नहीं है तो क्या होगा?
हरसिमरनब

@ श्यामल-पारिख यह html ईमेल के लिए काम नहीं करेगा, लेकिन आम तौर पर ईमेल संदेशों के साथ एक सादा संदेश भी शामिल होता है
maembe

25

शुक्रिया, Goleg, regexes के लिए! वास्तव में मदद की। यह C # नहीं है, लेकिन वहां के गोगलर्स के लिए, यहाँ मेरी रूबी पार्सिंग स्क्रिप्ट है:

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

यह अब तक बहुत अच्छा काम किया है।


1
आपको एक रूबी सवाल करना चाहिए और इसे एसी # प्रश्न पर पोस्ट करने के बजाय इस कोड के साथ उत्तर देना चाहिए।
मैथ्यू

6
@ मैथ्यू, इसका न केवल एक सी # प्रश्न है, बल्कि एक ईमेल और ईमेल-पार्सिंग प्रश्न है। मेरी राय में पूरी तरह से प्रासंगिक।
ट्रेंट

@ नोट: C # टैग को तब हटा दिया जाना चाहिए।
मैथ्यू 21

7
मज़ेदार बात यह है कि मुझे यह सवाल Googling द्वारा इस विषय के लिए मिला (भाषा नहीं), और मुझे वास्तव में रूबी में कुछ लागू करने की आवश्यकता थी। तो, महाराज!
bratsche

2
यह अब तक की सबसे अच्छी प्रतिक्रिया है। रेगेक्स सुंदर भाषा अज्ञेय है। पोस्टिंग के लिए धन्यवाद
सुपर

11

ऐसा करने का सबसे आसान तरीका आपकी सामग्री में एक मार्कर रखकर है, जैसे:

--- कृपया इस पंक्ति के ऊपर उत्तर दें ---

जैसा कि आपको कोई संदेह नहीं है, उद्धृत पाठ को पार्स करना एक तुच्छ कार्य नहीं है क्योंकि विभिन्न ईमेल क्लाइंट अलग-अलग तरीकों से पाठ का उद्धरण करते हैं। इस समस्या को ठीक से हल करने के लिए आपको प्रत्येक ईमेल क्लाइंट के लिए खाता और परीक्षण करना होगा।

फेसबुक ऐसा कर सकता है, लेकिन जब तक आपके प्रोजेक्ट का बड़ा बजट नहीं होता, आप शायद नहीं कर सकते।

ओलेग ने "13 जुलाई 2012 को 13:09 पर, एक्सएक्सएक्स लिखा:" पाठ खोजने के लिए रेगेक्स का उपयोग करके समस्या को हल किया है। हालाँकि, यदि उपयोगकर्ता इस पाठ को हटा देता है, या ईमेल के नीचे उत्तर देता है, जैसा कि कई लोग करते हैं, तो यह समाधान काम नहीं करेगा।

इसी तरह अगर ईमेल क्लाइंट एक अलग दिनांक स्ट्रिंग का उपयोग करता है, या एक तारीख स्ट्रिंग शामिल नहीं करता है जो regex विफल हो जाएगा।


जब तक आप प्रत्येक बार आपके द्वारा उत्तर देने के लिए उस पंक्ति को नहीं डालते, तब तक उत्तरों के साथ यह दृष्टिकोण विफल हो जाता है।
jpw

1
हां, इसमें कमियां हैं। यदि उपयोगकर्ता लाइन स्ट्रिंग के ऊपर उत्तर को हटाता है तो आपका उत्तर विफल हो जाएगा। मैं इस मामले को पकड़ता हूं और उपयोगकर्ता को एक सीधा संदेश भेजता हूं जिससे उन्हें पता चलता है कि उनका संदेश विफल हो गया है, वेब ऐप के माध्यम से उत्तर देने के लिए एक लिंक। अधिकांश उपयोगकर्ता बहुत अधिक परेशानी के बिना इसका उपयोग करने में सक्षम प्रतीत होते हैं।
सुपरलाइनरी

यह स्वीकृत उत्तर होना चाहिए। हालाँकि, मैं यह जानकारी जोड़ूंगा कि यदि रेखा हटा दी जाती है तो उत्तर सफल नहीं होगा।
बेनी

@ बेनी - हां, अगर लाइन हटा दी जाती है तो यह विफल हो जाएगा। दुर्भाग्य से, ईमेल क्लाइंट में टेक्स्ट को उद्धृत करने का कोई एक मानक तरीका नहीं है। उस स्थिति में जहां रेखा को हटा दिया जाता है, आप सभी पाठ को उत्तर के रूप में मान सकते हैं। मुझे नहीं लगता कि इस मामले में एक सही समाधान संभव है।
Jan१

@superluminary मेरा मतलब था, मैं इसे लाइन में जोड़ूंगा। तो यह कुछ ऐसा है -- Please reply above this line. DO NOT REMOVE IT! --। इसके अलावा, मैंने जो अनुभव किया वह यह है कि यह हमेशा काम नहीं करेगा क्योंकि कुछ ईमेल क्लाइंट xxx wrote on <datetime>:पूरे उद्धरण से पहले एक लाइन जोड़ते हैं और इसलिए उस लाइन से पहले। इस लाइन को रेगेक्स के साथ पार्स किया जा सकता है, हालांकि यह अलग-अलग भाषाओं में और ईमेल क्लाइंट अलग होने के बाद एक अलग प्रारूप में हो सकता है।
बेनी

6

ई-मेल में उत्तर का कोई सार्वभौमिक संकेतक नहीं है। सबसे अच्छा आप कर सकते हैं सबसे आम और पार्स नए पैटर्न को पकड़ने की कोशिश करते हैं जैसा कि आप उन पर आते हैं।

ध्यान रखें कि कुछ लोग उद्धृत पाठ के अंदर उत्तर देते हैं (उदाहरण के लिए मेरा बॉस उसी पंक्ति के प्रश्नों का उत्तर देता है जैसा मैंने उनसे पूछा था) इसलिए आप जो भी करते हैं, आप कुछ जानकारी खो सकते हैं जिसे आप रखना पसंद करेंगे।


जीमेल करता है ... कम से कम यह करने के लिए लगता है। क्या मुझे याद है कि कुछ थ्रेड आईडी है जो मूल और उत्तरों के बीच नहीं बदलती है ...
kenny

जीमेल अन्य ईमेल क्लाइंट के रूप में जोड़ सकता है, लेकिन यह ईमेल का एक मानक नहीं है और न ही आप कुछ गिन सकते हैं
3Doubloons

5

यहाँ मेरा @ संस्करण है @ hurshagrawal का रूबी कोड। मैं नहीं जानता कि रूबी वास्तव में अच्छी तरह से है, इसलिए यह बंद हो सकता है, लेकिन मुझे लगता है कि मुझे यह सही लगा।

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();
}

3

यदि आप मूल संदेश (जैसे वेब एप्लिकेशन से सूचनाएँ) को नियंत्रित करते हैं, तो आप एक विशिष्ट, पहचान योग्य हेडर रख सकते हैं और मूल पोस्ट के लिए सीमांकक के रूप में उपयोग कर सकते हैं।


0

यह एक अच्छा उपाय है। इतनी देर खोज करने के बाद मिला।

एक जोड़, जैसा कि ऊपर उल्लेख किया गया है, यह मामला बुद्धिमान है, इसलिए उपरोक्त अभिव्यक्तियों ने मेरे जीमेल और आउटलुक (2010) प्रतिक्रियाओं को सही ढंग से पार्स नहीं किया, जिसके लिए मैंने निम्नलिखित दो रेगेक्स (ओं) को जोड़ा। किसी भी मुद्दे के लिए मुझे बताएं।

//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),

चियर्स


किसी को भी इसके php संस्करण के लिए मदद कर सकते हैं?
user4271704

इसे php संस्करण के लिए जांचें। stackoverflow.com/questions/14916618/… github.com/willdurand/EmailReplyParser
FullStackDev

-1

यह पुरानी पोस्ट है, हालांकि, निश्चित नहीं है कि आप जानते हैं कि गीथब के पास जवाब देने के लिए रूबी का काम है । यदि आप .NET का उपयोग करते हैं, तो मेरे पास https://github.com/EricJWHuang/EmailReplyParser पर एक .NET है।


1
बाहरी संसाधनों के लिंक को प्रोत्साहित किया जाता है, लेकिन कृपया लिंक के चारों ओर संदर्भ जोड़ें ताकि आपके साथी उपयोगकर्ताओं को यह पता चले कि यह क्या है और क्यों है। हमेशा एक महत्वपूर्ण लिंक का सबसे प्रासंगिक हिस्सा उद्धृत करें, यदि लक्ष्य साइट उपलब्ध नहीं है या स्थायी रूप से ऑफ़लाइन है।
पेबिलियोस

क्या आप उस पुस्तकालय को अद्यतित रख रहे हैं? मुझे पता चला क्योंकि C # लाइब्रेरी ने ऑफिस 365 से आउटलुक के एक साधारण ईमेल को पार्स करना उचित नहीं समझा। तब मैंने रूबी सोर्स कोड में देखा और पाया कि उनके टेस्ट के मामलों में एक समान टेस्ट केस था, इसलिए स्पष्ट रूप से उन्हें लगता है कि उन्हें पार्स करना चाहिए। यह।
ग्रेग वेरस

-1

यदि आप SigParser.com के एपीआई का उपयोग करते हैं , तो यह आपको एकल ईमेल टेक्स्ट स्ट्रिंग से उत्तर श्रृंखला में सभी टूटे हुए ईमेलों की एक सरणी देगा। इसलिए यदि 10 ईमेल हैं, तो आपको सभी 10 ईमेल के लिए टेक्स्ट मिल जाएगा।

यहाँ छवि विवरण दर्ज करें

आप यहाँ विस्तृत एपीआई युक्ति देख सकते हैं।

https://api.sigparser.com/

यहाँ छवि विवरण दर्ज करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.