2009-02-14 21 views
10

मैं ईमेल के सादा पाठ प्रतिलेखों से ईमेल पते निकालने का प्रयास कर रहा हूं। मैंने पते को खोजने के लिए थोड़ा सा कोड एकत्र किया है, लेकिन मुझे नहीं पता कि यह उनके बीच भेदभाव कैसे करें; अभी यह फ़ाइल में सभी ईमेल पतों को थूकता है। मैं इसे बनाना चाहता हूं, इसलिए यह केवल उन पते को थूकता है जो "से:" और कुछ वाइल्डकार्ड वर्णों से पहले होते हैं, और ">" के साथ समाप्त होते हैं (क्योंकि ईमेल [नाम] < [ईमेल] के रूप में सेट किए गए हैं>)।ईमेल टेक्स्ट से "प्रेषक" पते को पार्सिंग

यहाँ अब कोड है:

import re #allows program to use regular expressions 
foundemail = [] 
#this is an empty list 

mailsrch = re.compile(r'[\w\-][\w\-\.][email protected][\w\-][\w\-\.]+[a-zA-Z]{1,4}') 
#do not currently know exact meaning of this expression but assuming 
#it means something like "[stuff]@[stuff][stuff1-4 letters]" 

     # "line" is a variable is set to a single line read from the file 
# ("text.txt"): 
for line in open("text.txt"): 

    foundemail.extend(mailsrch.findall(line)) 

    # this extends the previously named list via the "mailsrch" variable 
     #which was named before 

print foundemail 

उत्तर

2

मैं उस अतिरिक्त अभिव्यक्ति को विस्तारित करके आप करूँगा जिसमें आप जिस अतिरिक्त टेक्स्ट से मेल खाना चाहते हैं उसे शामिल करने के लिए उपयोग कर रहे हैं।

[\w\-][\w\-\.][email protected][\w\-][\w\-\.]+[a-zA-Z]{1,4} 
  • [\w\-] किसी भी "शब्द" अक्षर से मेल खाता (अक्षर, अंक, या अंडरस्कोर), या एक हाइफन
  • [\w\-\.]+ मैचों (किसी भी शब्द चरित्र: तो सबसे पहले, मुझे समझाने क्या कि regex करता है चलो या हाइफन या अवधि) एक या अधिक बार
  • @ एक शाब्दिक से मेल खाता है '@'
  • [\w\-] एक शब्द चरित्र या हाइफन से मेल खाता है
  • [\w\-\.]+ मैचों में एक या अधिक शब्द वर्ण, हाइफ़न, और/या अवधि
  • [a-zA-Z]{1,4} मैचों 1, 2, 3, या 4 लोअरकेस या अपरकेस पत्र

अब, करने के लिए अपने प्रयोजनों के लिए इस संशोधित करने, के regex भागों "से" मैच के लिए, नाम, और कोण कोष्ठक जोड़ें:

From: [\w\s]+?<([\w\-][\w\-\.][email protected][\w\-][\w\-\.]+[a-zA-Z]{1,4})> 
  • From: मैच शाब्दिक पाठ "से:"
  • [\w\s]+? एक या अधिक लगातार शब्द वर्ण या अंतरिक्ष वर्णों से मेल खाता है। प्रश्न चिह्न मैच को लालची बनाता है, इसलिए यह पूरी तरह से नियमित रूप से मिलान करने की इजाजत देकर कुछ पात्रों से मेल खाएगा (इस मामले में, शायद यह आवश्यक नहीं है, लेकिन यह इस बात से मेल को और अधिक कुशल बनाता है तुरंत बाद में एक शब्द चरित्र या अंतरिक्ष चरित्र नहीं आता है)।
  • < एक शाब्दिक कम-से-कम चिह्न (उद्घाटन कोण ब्रैकेट) से मेल खाता है
  • आपके द्वारा पहले की समान नियमित अभिव्यक्ति अब कोष्ठक से घिरा हुआ है। यह इसे कैप्चरिंग समूह बनाता है, ताकि आप regex के उस भाग से मेल खाने वाले पाठ को प्राप्त करने के लिए m.group(1) पर कॉल कर सकें।
  • > से मेल खाता है एक शाब्दिक अधिक से अधिक हस्ताक्षर

के बाद से regex अब का उपयोग करता है समूहों पर कब्जा करने के लिए, अपने कोड के रूप में अच्छी तरह से एक छोटे से बदलने के लिए की आवश्यकता होगी:

import re 
foundemail = [] 

mailsrch = re.compile(r'From: [\w\s]+?<([\w\-][\w\-\.][email protected][\w\-][\w\-\.]+[a-zA-Z]{1,4})>') 

for line in open("text.txt"): 
    foundemail.extend([m.group(1) for m in mailsrch.finditer(line)]) 

print foundemail 

कोड [m.group(1) for m in mailsrch.finditer(line)] एक सूची का उत्पादन नियमित अभिव्यक्ति द्वारा प्राप्त प्रत्येक मैच से पहले कैप्चरिंग समूह (याद रखें, वह कोष्ठक में हिस्सा था) का।

+0

हे, पोस्ट की तरह दिखता है जबकि मैं अभी भी मेरा टाइप कर रहा था। हम एक ही अंत परिणाम के बारे में आए, लेकिन आप वास्तव में mailsrc.findall() का उपयोग कर सकते हैं - यदि केवल एक समूह है तो यह उस समूह के लिए मैचों की एक सूची देता है ताकि सूची समझ की आवश्यकता से बचा जा सके। – Jay

+0

यह सही है, धन्यवाद! मैं जय की कोशिश भी करूंगा ताकि मैं कुछ अलग संस्करण प्राप्त कर सकूं। व्यापक स्पष्टीकरण के लिए भी धन्यवाद। –

+0

दिलचस्प, मुझे नहीं पता था कि ... कार्य करने के लिए एक अजीब तरीका है:? –

0

अगर आप यथोचित सुनिश्चित करें कि इन ईमेल पतों युक्त पंक्तियों का खाली स्थान के साथ शुरू किया जा सकता है "से:" आप बस कर सकते हैं:

addresslines = [] 
for line in open("text.txt"): 
    if line.strip().startswith("From:"): 
     addresslines.append(line) 

फिर बाद में - या उन्हें सूची में जोड़ने पर - आप एड्रेसलाइन आइटम को सटीक रूप से देने के लिए परिष्कृत कर सकते हैं जो आप चाहते हैं

+0

एचएम, मुझे इसे गलत तरीके से कार्यान्वित करना होगा ... यह या तो रिक्त रहता है या पूरी सूची को दिखाता है जो मैं पहले प्राप्त कर रहा था। –

0

"[सामान] @ [सामान] [सामान 1-4 अक्षरों]" रिग के बारे में है एचटी, लेकिन अगर आप चाहते थे कि आप एक चाल का उपयोग करके नियमित अभिव्यक्ति को डीकोड कर सकें तो मुझे here पता चला। इस तरह एक इंटरैक्टिव अजगर सत्र में संकलन() कार्य करें:

mailsrch = re.compile(r'[\w\-][\w\-\.][email protected][\w\-][\w\-\.]+[a-zA-Z]{1,4}', 128) 

यह पता निम्नलिखित प्रिंट होगा:

in 
    category category_word 
    literal 45 
max_repeat 1 65535 
    in 
    category category_word 
    literal 45 
    literal 46 
literal 64 
in 
    category category_word 
    literal 45 
max_repeat 1 65535 
    in 
    category category_word 
    literal 45 
    literal 46 
max_repeat 1 4 
    in 
    range (97, 122) 
    range (65, 90) 

कौन सा है, अगर आप एक तरह से इसकी आदत हो सकते हैं, आप वास्तव में कैसे पता चलता आरई काम करता है। क्योंकि यह हैडर लाइनों की उम्मीद कर रहा है

>>> from email.utils import parseaddr 

>>> parseaddr('From: [email protected]') 
('', '[email protected]') 

>>> parseaddr('From: Van Gale <[email protected]>') 
('Van Gale', '[email protected]') 

>>> parseaddr(' From: Van Gale <[email protected]> ') 
('Van Gale', '[email protected]') 

>>> parseaddr('blah abdf From: Van Gale <[email protected]> and this') 
('Van Gale', '[email protected]') 

दुर्भाग्य से यह केवल प्रत्येक पंक्ति में पहले ईमेल पाता है, लेकिन हो सकता है कि ठीक है:

+0

सवाल का काफी जवाब नहीं देता है लेकिन यह एक साफ चाल है ... यह इंगित करने के लिए धन्यवाद :-) –

32

इस बाहर का प्रयास करें?

+1

परसेडर वास्तव में केवल पतासूची (addr) .addresslist [0] है ताकि आप पता सूची (addr) कर सकें। उन सभी –

2
mailsrch = re.compile(r'[\w\-][\w\-\.][email protected][\w\-][\w\-\.]+[a-zA-Z]{1,4}') 

अभिव्यक्ति टूटने:

[\w-]: किसी भी शब्द चरित्र (अल्फान्यूमेरिक, प्लस को रेखांकित) या एक पानी का छींटा

[\w-.]+: किसी भी शब्द चरित्र, एक पानी का छींटा, या एक अवधि/डॉट, एक या अधिक बार

@: शाब्दिक @ प्रतीक

[\w-][\w-.]+: किसी भी शब्द चार या दास एच, किसी भी शब्द चार, डैश, या अवधि के बाद एक या अधिक बार।

[a-zA-Z]{1,4}: कोई वर्णमाला वर्ण 1-4 बार।

import re 

foundemail = [] 
mailsrch = re.compile(r'^From:\s+.*<([\w\-][\w\-\.][email protected][\w\-][\w\-\.]+[a-zA-Z]{1,4})>', re.I | re.M) 
foundemail.extend(mailsrch.findall(open('text.txt').read())) 

print foundemail 
2

ईमेल का सादा पाठ संस्करण पार्स करने के लिए ईमेल और मेलबॉक्स संकुल का उपयोग करें:

इस मैच केवल लाइनों From: से आरंभ करते हुए < और > प्रतीकों में लिपटे बनाने के लिए। यह इसे किसी ऑब्जेक्ट में परिवर्तित कर देगा जो 'से' फ़ील्ड में सभी पतों को निकालने में सक्षम होगा।

यदि आप अन्य हेडर फ़ील्ड या संदेश निकाय को संसाधित करने की आवश्यकता है, तो आप संदेश पर कई अन्य विश्लेषण भी कर सकते हैं।

एक त्वरित उदाहरण के रूप में, निम्न (अवांछित) कोड को यूनिक्स स्टाइल मेलबॉक्स में सभी संदेश पढ़ना चाहिए, और सभी 'से' हेडर प्रिंट करना चाहिए।

import mailbox 
import email 

mbox = mailbox.PortableUnixMailbox(open(filename, 'rU'), email.message_from_file) 

for msg in mbox: 
    from = msg['From'] 
    print from 
8
import email 
msg = email.message_from_string(str) 

# or 
# f = open(file) 
# msg = email.message_from_file(f) 

msg['from'] 

# and optionally 
from email.utils import parseaddr 
addr = parseaddr(msg['from']) 
1

मोटे तौर पर, आप कर सकते हैं:

from email.utils import parseaddr 

foundemail = [] 
for line in open("text.txt"): 
    if not line.startswith("From:"): continue 
    n, e = parseaddr(line) 
    foundemail.append(e) 
print foundemail 

यह इस्तेमाल में निर्मित अजगर parseaddr समारोह पते के बिना, रेखा (के रूप में अन्य उत्तर द्वारा प्रदर्शन) से से बाहर पार्स करने के लिए पूरे संदेश को पार्स करने के लिए ओवरहेड जरूरी है (उदाहरण के लिए अधिक पूर्ण फीचर्ड ईमेल और मेलबॉक्स पैकेज का उपयोग करके)। यहां लिपि बस किसी भी लाइन को छोड़ देती है जो "से:" से शुरू नहीं होती है। चाहे उपरांत आपके लिए महत्वपूर्ण है, इस पर निर्भर करता है कि आपका इनपुट कितना बड़ा है और आप कितनी बार इस ऑपरेशन कर रहे होंगे।

संबंधित मुद्दे