Thread SpamFilter Email in Perl "simulieren"
(9 answers)
Opened by J0ke at 2016-11-15 10:36
Erstmal: use strict;, use warnings; ist geesetzt => gut.
Zweitens: Es werden weder lexikalischen Filehandle noch die 3-Argument-Form von open() verwendet => schlecht Wenn Du nicht weißt wovon ich rede, such hier im Forum danach oder les Dir Modern Perl durch. Drittens: Wenn Leute erstmal ganze Files in Arrays laden, frage ich mich, ob das wirklich unumgänglich ist. Was hier gemacht werden muss: Jede Zeile im Filter mit jeder Zeile in der Mail vergleichen => zwei verschachtelte Schleifen => es macht Sinn die Daten der inneren Schleife im Speicher zu halten, von der äußeren Schleife braucht man immer nur einen Eintrag. Da genügt zeilenweises einlesen. Vom Speicherbedarf ist es i.A. sinnvoll, die kleinere Datei im Speicher zu halten. In diesem Fall würde ich aber unabhängig von der Größe den Filter in den Speicher nehmen, da es (a) wahrscheinlicher ist, dass später mehrere Mails durch den Filter gejagt werden statt mehrere Filter auf eine Mail losgelassen werden und (b) man die Ausgaben gerne in der Reihenfolge der Mail und nicht der Filterausdrücke haben will. Also sieht der Algorithmus grob wie folgt aus: 1. Filter in ein Array einlesen 2. Counter initialisieren 3. Eine Zeile von der Mail einlesen 4. Zeilen-Nummer inkrementieren 5. das Filter-Array durchgehen und jeden Eintrag gegen die aktuelle Zeile der Mail matchen 6. Falls ein Treffer vorliegt den Count inkrementieren und den Treffer ausgeben 7. nächsten Filtereintrag nehmen 8. nächste Zeile aus der Mail nehmen Da Du die Filtereinträge beim Vergleich nur als Regex aber nicht im Plaintext brauchst, empfehle ich Dir im Filter-Array gleich die Regex abzulegen. Dann musst Du die Umwandlung "plain text" => qr// nur einmal machen anstatt sie für jede Mailzeile zu wiederholen. Denk dabei daran, Sonderzeichen im Filterstring zu escapen so dass z.B. '.' wirklich nur einen Punkt matched und nicht als Wildcard aufgefasst wird. |