Parsing "Von" Adressen aus E-Mail-Text

Ich versuche, E-Mail-Adressen aus einfachen Text-Transkripten von E-Mails zu extrahieren. Ich habe zusammen ein paar Code gepflastert, um die Adressen selbst zu finden, aber ich weiß nicht, wie man es zwischen ihnen unterscheiden kann. Im Moment spuckt es einfach alle E-Mail-Adressen in der Datei aus. Ich möchte es so machen, dass es nur Adressen ausspuckt, die von "From:" und einigen Wildcard-Zeichen vorangegangen sind und mit ">" enden (weil die E-Mails als Von [name] <[email]> eingerichtet sind ).

Hier ist der Code jetzt:

import re #allows program to use regular expressions foundemail = [] #this is an empty list mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\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 

8 Solutions collect form web for “Parsing "Von" Adressen aus E-Mail-Text”

Ich würde es tun, indem ich den regulären Ausdruck erweitere, den du benutzt hast, um den zusätzlichen Text einzuschließen, den du treffen möchtest. Also zuerst, lassen Sie mich erklären, was diese Regex tut:

 [\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4} 
  • [\w\-] entspricht jedem "Wort" -Zeichen (Buchstabe, Zahl oder Unterstrich) oder einem Bindestrich
  • [\w\-\.]+ Streichhölzer (beliebige Wortzeichen oder Bindestrich oder Periode) ein oder mehrere Male
  • @ Entspricht einem wörtlichen '@'
  • [\w\-] entspricht einem Wortzeichen oder Bindestrich
  • [\w\-\.]+ Entspricht einem oder mehreren Wortzeichen, Bindestrichen und / oder Perioden
  • [a-zA-Z]{1,4} entspricht 1, 2, 3 oder 4 Kleinbuchstaben oder Großbuchstaben

Um dies für Ihre Zwecke zu ändern, fügen wir Regex-Teile hinzu, um "Von", dem Namen und den spitzen Klammern zu entsprechen:

 From: [\w\s]+?<([\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4})> 
  • From: entspricht dem wörtlichen Text "Von:"
  • [\w\s]+? Entspricht einem oder mehreren aufeinanderfolgenden Wortzeichen oder Leerzeichen. Das Fragezeichen macht das Spiel nicht gierig, so dass es so wenig Charaktere wie möglich zusammenbringen wird, während immer noch der ganze reguläre Ausdruck passen kann (in diesem Fall ist es wahrscheinlich nicht notwendig, aber es macht das Spiel effizienter, da das Ding das Kommt sofort danach kein Wortcharakter oder Raumzeichen).
  • < Entspricht einem Literal weniger als Zeichen (Öffnungswinkelklammer)
  • Der gleiche reguläre Ausdruck, den Sie vorher hatten, ist jetzt von Klammern umgeben. Dies macht es zu einer Erfassungsgruppe , so dass man m.group(1) anrufen kann, um den von diesem Teil der Regex abgestimmten Text zu erhalten.
  • > Entspricht einem Literal größer als Zeichen

Da die Regex jetzt Capture-Gruppen verwendet, muss Ihr Code auch ein wenig ändern:

 import re foundemail = [] mailsrch = re.compile(r'From: [\w\s]+?<([\w\-][\w\-\.]+@[\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 

Der Code [m.group(1) for m in mailsrch.finditer(line)] erzeugt aus der ersten Erfassungsgruppe eine Liste aus der ersten Erfassungsgruppe (erinnere dich daran, dass der Teil in Klammern war) aus jeder Übereinstimmung, die durch den regulären Ausdruck gefunden wurde.

Probieren Sie es aus:

 >>> from email.utils import parseaddr >>> parseaddr('From: vg@m.com') ('', 'vg@m.com') >>> parseaddr('From: Van Gale <vg@m.com>') ('Van Gale', 'vg@m.com') >>> parseaddr(' From: Van Gale <vg@m.com> ') ('Van Gale', 'vg@m.com') >>> parseaddr('blah abdf From: Van Gale <vg@m.com> and this') ('Van Gale', 'vg@m.com') 

Leider findet es nur die erste E-Mail in jeder Zeile, weil es Kopfzeilen erwartet, aber vielleicht ist das ok?

 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']) 
 mailsrch = re.compile(r'[\w\-][\w\-\.]+@[\w\-][\w\-\.]+[a-zA-Z]{1,4}') 

Ausdruckszusammenbruch:

[\w-] : jedes Wort Zeichen (alphanumerisch, plus Unterstrich) oder ein Bindestrich

[\w-.]+ : Jedes Wort Zeichen, ein Bindestrich, oder eine Periode / Punkt, ein oder mehrere Male

@ : Wörtlich @ symbol

[\w-][\w-.]+ : Jedes Wort char oder Bindestrich, gefolgt von jedem Wort char, Bindestrich oder Periode ein oder mehrere Male.

[a-zA-Z]{1,4} : jedes alphabetische Zeichen 1-4 mal.

Um dieses Spiel zu machen, werden nur Zeilen beginnend mit From: und in <und> Symbole eingehüllt:

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

Verwenden Sie die E-Mail- und Mailbox-Pakete, um die Klartextversion der E-Mail zu analysieren. Dies wird es in ein Objekt umwandeln, das es ermöglicht, alle Adressen im Feld 'Von' zu extrahieren.

Sie können auch eine Menge anderer Analysen auf die Nachricht machen, wenn Sie andere Header-Felder oder den Nachrichtentext verarbeiten müssen.

Als ein kurzes Beispiel sollte der folgende (ungetestete) Code alle Nachrichten in einem Unix-Style-Postfach lesen und alle 'from' Header ausdrucken.

 import mailbox import email mbox = mailbox.PortableUnixMailbox(open(filename, 'rU'), email.message_from_file) for msg in mbox: from = msg['From'] print from 

Grob gesprochen, können Sie:

 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 

Dies nutzt die eingebaute Python-Parseaddr-Funktion, um die Adresse aus der Zeile zu analysieren (wie durch andere Antworten gezeigt), ohne dass der Overhead unbedingt die gesamte Nachricht analysiert (z. B. durch die Verwendung der volleren E-Mail- und Postfachpakete). Das Skript hier überspringt einfach alle Zeilen, die nicht mit "From:" beginnen. Ob der Overhead für dich hängt davon ab, wie groß deine Eingabe ist und wie oft wir diesen Vorgang machen werden.

Wenn Sie sich einigermaßen sicher sein können, dass Zeilen, die diese E-Mail-Adressen enthalten, mit dem Whitespace beginnen, gefolgt von "From:" können Sie dies einfach tun:

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

Dann später – oder beim Hinzufügen zu der Liste – können Sie die Adresslinien Elemente verfeinern, um genau das zu geben, was Sie wollen

"[Stuff] @ [stuff] [stuff1-4 letters]" ist etwa richtig, aber wenn du wolltest, könntest du den regulären Ausdruck mit einem Trick entschlüsseln, den ich hier gerade herausgefunden habe . Mache das kompilieren () in einer interaktiven Python-Session wie folgt:

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

Es wird folgendes ausdrucken:

 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) 

Welches, wenn man sich irgendwie daran gewöhnen kann, zeigt Ihnen genau, wie die RE funktioniert.

  • Python, lxml - Zugriffstext
  • Python tkinter scrollbar und text widget Fragen
  • Was ist eine effiziente Datenstruktur für Token-Daten in Python?
  • Ocr'ing Anwendungstext (nicht gescannt, NICHT captchas)
  • So prüfen Sie, ob eine Liste von Zeichenfolgen in zwei separaten Dateien vorhanden ist
  • Einbetten von Text in PNG
  • Entfernen von nicht brechenden Räumen aus Strings mit Python
  • Wie lese ich bestimmte Zeichen aus Zeilen in einer Textdatei mit Python?
  • Python ersetzt mehrere Strings
  • PyQt: So fügen Sie Text am Cursor in QTableView ein
  • Python oder Java für Textverarbeitung (Text Mining, Information Retrieval, natürliche Sprache Verarbeitung)
  • Python ist die beste Programmiersprache der Welt.