Seite 1 von 1

Suche nach Mail-Adressen

Verfasst: Mittwoch 23. April 2008, 15:41
von HL
Hallo,

in einem String suche ich nach "@domain.tld".

Ich bekommen das @-Zeichen allerdings als extra Treffer zurück?! Wie kann ich das verhindern?

Verfasst: Mittwoch 23. April 2008, 15:50
von BlackVivi
._.

Code: Alles auswählen

In [1]: text = "lorem ipSUm blabla@domain.de blabla bla@domain.de"

In [2]: emailadressen = [x for x in text.split() if "@domain.de" in x]

In [3]: emailadressen
Out[3]: ['blabla@domain.de', 'bla@domain.de']
(Ich mag' immer noch keine regulären Ausdrücke...)

Re: Suche nach Mail-Adressen

Verfasst: Mittwoch 23. April 2008, 16:32
von Leonidas
HL hat geschrieben:in einem String suche ich nach "@domain.tld".

Ich bekommen das @-Zeichen allerdings als extra Treffer zurück?! Wie kann ich das verhindern?
Anders suchen.

Mal ehrlich, erwartest du, dass wir erraten wie du danach suchst? Wenn du Code stellst, dann kann man eine Aussage treffen.

Verfasst: Donnerstag 24. April 2008, 07:59
von HL
@Leonidas: Nein, das habe ich nicht erwartet. Eher erwartete ich so etwas wie "Das @ muss so uns so maskiert werden" oder ähnliches, da ich mir mit meinem Code eigentlich sicher war.

Was sich dann später rausstellte war, dass ich in der "DateiMitDomainsZumSuchen.txt" eine Zeile übersehen hatte in der tatsächlich nur ein @ stand... hatte mir also selbst ein Bein gestellt :?

Hier aber dennoch der Code:

Code: Alles auswählen

file1 = open("DateiMitTextUndMailAdressen.txt","r")
for line1 in file1: 
    line1 = line1.strip()
        
    file2 = open("DateiMitDomainsZumSuchen.txt", "r")
    for line2 in file2:
        line2 = line2.strip()
        
        if line2 in line1:
            print line1
            
    file2.close()
file1.close()

Verfasst: Donnerstag 24. April 2008, 08:10
von Leonidas
Du bist dir sicher, dass du den Code so haben willst? D.h. bei jeder Zeile die Datei mit den Domains komplett neu einlesen?

Verfasst: Donnerstag 24. April 2008, 10:40
von Y0Gi
Dem stimme ich zu, die willst du vermutlich lieber im Speicher halten.

Zudem empfehle ich dir einen Blick auf das `with`-Statement.

Verfasst: Donnerstag 24. April 2008, 10:50
von shakebox
@Y0Gi

Wenn ich da mal rein aus Interesse zwischengraetschen darf: was meinst Du denn mit dem "with"-Statement? Das finde ich weder per help() noch taucht das im Index meines Exemplares der Python Essential Reference auf.

Bin ja auch neu in Python und versuche deshalb hier bei allen Tipps und Hinweisen mitzulernen :)

Danke!

Verfasst: Donnerstag 24. April 2008, 10:57
von EyDu
@shakebox: Dann zieh doch einfach mal die Dokumentation zur Hilfe ;-) Und ein Statement kannst du mit "help" natürlich nicht finden.

Verfasst: Donnerstag 24. April 2008, 11:06
von Y0Gi
Beispiel vorher:

Code: Alles auswählen

f = open('foo.txt')
for line in f:
    print line
f.close()
Beispiel nachher:

Code: Alles auswählen

from __future__ import with_statement  # in Python 2.5

with open('foo.txt') as f:
    for line in f:
        print line
Dabei wird die Datei automatisch beim Verlassen des `with`-Blocks geschlossen, auch wenn ein Fehler aufgetreten ist (sonst müsste man da mit `try`/`finally` ran - etwas unschön).


P.S.: Das `with`-Statement kann auch in anderen Bereichen verwendet werden, z.B. mit Locks oder Sockets. Leider sind diese nicht immer entsprechend vorbereitet (ich hoffe, das wird in Python 2.6 so sein?!), so dass man mit `contextlib.closing` den Aufruf erst noch wrappen muss.

Verfasst: Donnerstag 24. April 2008, 11:41
von HL
Hey, Danke für die Tipps! Als Anfänger kann ich die sehr gut gebrauchen!

Mein Code sieht jetzt wie folgt aus und läuft 4x schneller:

Code: Alles auswählen

#!/usr/bin/env python2.5

from __future__ import with_statement

domains = []

with open('domains.txt', "r") as dfile:
    for line in dfile:
        line = line.strip()
        domains.append(line)
    dfile.close()

with open("DateiMitDomainsZumSuchen.txt", "r") as f:
    for line in f: 
        line = line.strip()

        for domain in domains:
            if domain in line:
                print line
    f.close()
Habe ich die Tipps richtig verstanden?

Verfasst: Donnerstag 24. April 2008, 11:51
von EyDu

Code: Alles auswählen

#!/usr/bin/env python2.5

from __future__ import with_statement

def extract_domains(domain_file, source_file):
    with open(domain_file, "r") as dfile:
        domains = set(x.strip() for x in dfile)

    with open(source_file"r") as fp:
        lines = set(line.strip() for line if fp for d in domains if d in line.strip())

    return lines
Ich habe deinen Code mal noch etwas gekürzt. Das Schließen der Dateien wird durchdie with-Statements überflüssig.

Das doppelte "line.strip()" könnte man noch durch "imap" im Modul "intertools" eleminieren.

Verfasst: Donnerstag 24. April 2008, 12:39
von HL
Danke, aber ich finde Deine Variante nicht sehr übersichtlich bzw. nicht gut lesbar. Dir ging es vermutlich ähnlich, denn es hat sich auch ein kleiner Fehler eingeschlichen ;-)

Code: Alles auswählen

lines = set(line.strip() for line if fp for d in domains if d in line.strip())

Code: Alles auswählen

lines = set(line.strip() for line in fp for d in domains if d in line.strip())
Hat Deine Variante, ausser dass sie kürzer ist, noch weitere Vorteile?

Verfasst: Donnerstag 24. April 2008, 13:00
von Leonidas
HL hat geschrieben:Danke, aber ich finde Deine Variante nicht sehr übersichtlich bzw. nicht gut lesbar.
Ich hingegen finds gut. Der erste Teil gibt dir eine Menge an Domains zurück (denn eigentlich willst du ja eine Menge, keine Liste). Dabei wird die Datei komplett durchlaufen, die Zeilen gestrippt und in eine Menge konvertiert und der zweite Teil... hmm, ja die ist schon etwas unübersichtlicher, da würde ich wohl auch auf mehrere Zeilen ausweichen.

Verfasst: Donnerstag 24. April 2008, 15:55
von EyDu
So ein in/if-Dreher kann schon mal passieren, ich teste den Code nach nicht vor dem Posten. Man kann natürlich auch den Generator in mehreren Zeilen schreiben:

Code: Alles auswählen

lines = set(line.strip() for line in fp 
                         for d in domains
                         if d in line.strip())

Verfasst: Donnerstag 24. April 2008, 17:09
von HL
Sorry, ich wollte nicht besserwisserisch oder unfreundlich rüberkommen - falls dieser Eindruck entstanden sein sollte.

Das mit der Menge und auch mit set, verstehe ich noch nicht ganz, ich muss halt noch viel lernen und bin Dankbar um jeden Zaunpfahl ;)

Verfasst: Donnerstag 24. April 2008, 18:25
von EyDu
HL hat geschrieben:Sorry, ich wollte nicht besserwisserisch oder unfreundlich rüberkommen - falls dieser Eindruck entstanden sein sollte.
Kamst du für mich gar nicht, die Einwände sind ja auch durchaus berechtigt.
HL hat geschrieben:Das mit der Menge und auch mit set, verstehe ich noch nicht ganz, ich muss halt noch viel lernen und bin Dankbar um jeden Zaunpfahl ;)
Der Vorteil an einer Menge ist, dass Elemente darin nur einmal enthalten sind. In einer Liste kannst du die selbe E-Mail-Adresse mehrfach ablegen in einer Menge geht das nicht mehr. Darauf kann eine Datenstruktur dann natürlich optimiert werden. Das bringt u.U. mehr Geschwindigkeit beim Prüfen, ob ein Element in der Liste vorhanden ist. Das macht sich zwar nur bei sehr vielen Tests bemerkbar, aber die Menge ist in diesem Fall halt die richtige Datenstruktur.

Und lass dich von dem Generator zwischen den Klammern beim "set" nicht irritieren. Es funktioniert z.B. auch "set([1,2,3,2,1])". Am besten schaust du mal in die Doku.