Probleme mit Durchsuchen eines Strings

Probleme mit Durchsuchen eines Strings

am 18.10.2007 13:14:12 von Daniel Krabbe

Hallo zusammen!
(Dies dürfte wohl eine der häufigsten Anreden im Netz sein ;-) )

Ich durchsuche einen langen String nach einem bestimmten Muster, konkret:
Eine E-Mail nach ihrem Empfänger anhand der Develop-To-Headerzeile.
In einem einfachen Beispiel klappte das auch gut, die Suche lieferte die Adresse wie
gewünscht. Lasse ich den gleichen Suchstring nun aber über den kompletten Mailheader
laufen kommt es zu folgendem Problem:

Normalerweise wird nach dem Durchlauf in

- $1 der Nutzername
- $2 die Domain
- $3 die TLD

gespeichert. Bei mir aber nicht mehr, hier steht plötzlich der komplette String in $1 und
$2, $3 bleibt leer.

Die zugehörigen Codezeilen:

$mail =~ /Delivered-To:\s*<([^\@]+)\@([^\.]+)([\.\w+]+)>/;
($user,$domain,$tld) = ($1,$2,$3);
$mailaddi = $user . $klaffe . $domain . $tld;
print "user: $user, klaffe: $klaffe, domain: $domain, tld: $tld \n\n";



#!/usr/bin/perl

use strict;
use warnings;

my $klaffe = "\@";
my $string = "Dd d rrwa rr Delivered-To: ";

$string =~ /Delivered-To:\s*<([^\@]+)\@([^\.]+)([\.\w+]+)>/;

my ($user,$domain,$net) = ($1,$2,$3);

my $mailaddi = $user . $klaffe . $domain . $net;

print "$mailaddi \n\n";


Die Zeilen als Extraprogramm liefern wie gewünscht "user@domain.tld.de".
Wo ist mein Verständnisfehler? Habe ich was übersehen?

Für Hilfe dankend,
Daniel

Re: Probleme mit Durchsuchen eines Strings

am 18.10.2007 13:26:00 von Roman Racine

Daniel Krabbe wrote:

> Hallo zusammen!
> (Dies dürfte wohl eine der häufigsten Anreden im Netz sein ;-) )
>
> Ich durchsuche einen langen String nach einem bestimmten Muster, konkret:
> Eine E-Mail nach ihrem Empfänger anhand der Develop-To-Headerzeile.
> In einem einfachen Beispiel klappte das auch gut, die Suche lieferte die
> Adresse wie gewünscht. Lasse ich den gleichen Suchstring nun aber über den
> kompletten Mailheader laufen kommt es zu folgendem Problem:
>
> Normalerweise wird nach dem Durchlauf in
>
> - $1 der Nutzername
> - $2 die Domain
> - $3 die TLD
>
> gespeichert. Bei mir aber nicht mehr, hier steht plötzlich der komplette
> String in $1 und $2, $3 bleibt leer.
>
> Die zugehörigen Codezeilen:
>
> $mail =~ /Delivered-To:\s*<([^\@]+)\@([^\.]+)([\.\w+]+)>/;
> ($user,$domain,$tld) = ($1,$2,$3);
> $mailaddi = $user . $klaffe . $domain . $tld;
> print "user: $user, klaffe: $klaffe, domain: $domain, tld: $tld \n\n";

Der Code hat allgemein einige Mängel. So würde er beispielsweise eine
Adresse der Art inbox@daniel.krabbe.example nicht richtig erkennen,
ausserdem fehlt der Regexp die Verankerung, so, dass sie ungewollt in
anderen Headerzeilen matchen kann.

Alternativer Vorschlag:

$mail =~ /^Delivered-To:\s+?\r?\n$/;

Gruss

Roman°
--
IRC-Freenode: #usenet-friends
http://www.usenet-friends.ch.vu/

Re: Probleme mit Durchsuchen eines Strings

am 18.10.2007 13:44:23 von Daniel Krabbe

Am 18.10.2007 13:14 Uhr schrieb Daniel Krabbe

> [ ...Beschreibung des Problems... ]
> Die zugehörigen Codezeilen:
>
> $mail =~ /Delivered-To:\s*<([^\@]+)\@([^\.]+)([\.\w+]+)>/;
> ($user,$domain,$tld) = ($1,$2,$3);
> $mailaddi = $user . $klaffe . $domain . $tld;
> print "user: $user, klaffe: $klaffe, domain: $domain, tld: $tld \n\n";
>
>
>
> [ ...Alternatives Programm... ]
>
> Wo ist mein Verständnisfehler? Habe ich was übersehen?


Ja, habe ich allerdings. Hatte noch Teile des alten Suchstringes verwendet, da stehen noch
die "<" und die ">" drin. Im gesuchten Headereintrag ist das aber nicht der Fall. So,
werde jetzt mal meinen Bildschirm putzen und danach nen Augenarzt-Termin machen.
Man, man, man war ich blind *kopfschüttel*

Der korrekte Suchstring, mit dem alles wunderbar funktioniert:


$mail =~ /Delivered-To:\s*([^\@]+)\@([^\.]+)([\.\w+]+)/;
($user,$domain,$tld) = ($1,$2,$3);
$mailaddi = $user . $klaffe . $domain . $tld;

> Für Hilfe dankend,
> Daniel

Nö, bei meiner eigenen Blindheit bedanke ich ich sicher nicht ;-)

Daniel

Re: Probleme mit Durchsuchen eines Strings

am 18.10.2007 13:49:34 von Daniel Krabbe

Am 18.10.2007 13:26 Uhr schrieb Roman Racine
>
> Alternativer Vorschlag:
>
> $mail =~ /^Delivered-To:\s+?\r?\n$/;

Moin.
Danke dir, sieht auch gut aus. Muss ihn jetzt nur noch meinen Bedürfnissen ohne die
umschließenden "<>" anpassen. Das sollte ich ja hinbekommen *hoff*.
Bildschirm ist jetzt zumindest sauber ;-)

> Gruss
>
> Roman°

Gruß Daniel

Re: Probleme mit Durchsuchen eines Strings

am 18.10.2007 13:57:17 von Roman Racine

Daniel Krabbe wrote:

> Am 18.10.2007 13:26 Uhr schrieb Roman Racine
>>
>> Alternativer Vorschlag:
>>
>> $mail =~ /^Delivered-To:\s+?\r?\n$/;
>
> Moin.
> Danke dir, sieht auch gut aus. Muss ihn jetzt nur noch meinen Bedürfnissen
> ohne die umschließenden "<>" anpassen. Das sollte ich ja hinbekommen
> *hoff*. Bildschirm ist jetzt zumindest sauber ;-)

Die obige Regexp geht sowohl mit als auch ohne umschliessende spitze
Klammern.

Verbesserung:
/^Delivered-To:\s+?\r?\n$/

Das klappt dann auch beispielsweise mit *@va-Adressen.

Gruss

Roman°
--
IRC-Freenode: #usenet-friends
http://www.usenet-friends.ch.vu/

Re: Probleme mit Durchsuchen eines Strings

am 18.10.2007 14:43:06 von Daniel Krabbe

Am 18.10.2007 13:57 Uhr schrieb Roman Racine
>
> Die obige Regexp geht sowohl mit als auch ohne umschliessende spitze
> Klammern. $mail =~ /^Delivered-To:\s+?\r?\n$/;
>
> Verbesserung:
> /^Delivered-To:\s+?\r?\n$/

Beide Zeilen sorgen bei mir für Fehlermeldungen. Werde jetzt gleich mal dem Ursprung
nachgehen.

###
Variante 1:
Use of uninitialized value in concatenation (.) or string at /skript.pl line 153,
chunk 1.

$mailaddi hier gleich $mail

###
Variante 2:
syntax error at skript.pl line 152, near "("
Execution of skript.pl aborted due to compilation errors.


###
Zeile 151-153:
$mail =~ /^Delivered-To:\s+?\r?\n$/;
($user,$domain,$tld) = ($1,$2,$3);
$mailaddi = $user . $klaffe . $domain . $tld;


Mein ursprünglicher Ansatz greift übrigens doch Adressen vom Typ

uservor.usernach@hallo.so.viele.dinge.hier.com.de

ab.

So, weiter testen. Danke für deine Hilfe!!!

> Gruss
>
> Roman°

Daniel

Re: Probleme mit Durchsuchen eines Strings

am 23.10.2007 12:39:04 von Daniel Krabbe

Ich komme einfach nicht weiter. Vielleicht hat ja noch jemand eine Idee. Egal welchen
Ausdruck ich nutze, Ergebnis ist eine Fehlermeldung:
Use of uninitialized value in concatenation (.) or string at
/etc/postfix/scripts/guteidee3.pl line 208, chunk 1.

Zeile 208 lautet:
$testvar = $user . $klaffe . $domain . $tld;

Die vorhergehenden Zeilen:

$header =~ /^To:\w*,?\w*?\r?\n$/m;
($user,$domain,$tld) = ($1,$2,$3);

Oh man, ich hasse es.

Hier mal ein Beispielheader, den ich durchsuche:

Return-Path:
Received: blabla1
Received: blabla2
Message-ID: <471A13F5.6070002@domain.tld>
Date: Sat, 20 Oct 2007 16:43:01 +0200
From: test, user
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.0.13) Gecko/20070809
Thunderbird/1.5.0.13 Mnenhy/0.7.5.0
MIME-Version: 1.0


==> To: test, user2

Subject: Testmail
X-Enigmail-Version: 0.94.4.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Diplom.FH-MailScanner: Found to be clean, Found to be clean
X-Spam-Status: No, No

Nach der markierten Zeile möchte ich suchen, wobei der Text vor der öffnenden, spitzen
Klammer aus null bis beliebig vielen Zeichen bestehen kann. Anzeigename des TB-Adressbuches.

Wer kann helfen???

Daniel

Re: Probleme mit Durchsuchen eines Strings

am 23.10.2007 13:12:02 von Dirk Krause

Daniel Krabbe wrote in
news:5o60uqFl45suU1@mid.individual.net:

> Ich komme einfach nicht weiter. Vielleicht hat ja noch jemand eine
> Idee. Egal welchen Ausdruck ich nutze, Ergebnis ist eine
> Fehlermeldung: Use of uninitialized value in concatenation (.) or
> string at /etc/postfix/scripts/guteidee3.pl line 208, chunk 1.
> ...
> $header =~ /^To:\w*,?\w*?\r?\n$/m;
> ($user,$domain,$tld) = ($1,$2,$3);

Hallo Daniel,
ich denke folgende Codefragment koennte Dir weiterhelfen.
Das @-Zeichen ist ja in Perl Kennzeichen für Arrays und muss z.B.
in auszudruckenden Strings einen Backslash vorangestellt bekommen.
Ich denke, das gilt auch fuer expressons beim Pattern Matching,
bin mir aber da nicht hundertprozentig sicher.
Warum bei Dir der uninitialied value auftritt, kann ich schlecht
nachvollziehen, da Du nur schreibtst, dass Pattern Matching vor der
Zuweisung stattgefunden hat. Der genaue Code liegt aber im Dunkeln.
Ich vermute aber mal, dass der Code fuer die Concatenation auch
dann durchlaufen wird, wenn das Pattern Matching nicht erfolgreich
war. Also testen, ob das Pattern Matching erfolgreich ist und nur
in diesem Fall die Concatenation durchfuehren.

while(<>)
{
$line = $_; chomp($line);
if($line =~ /^[Tt][Oo]:[^<]*<([^\@]+)\@(.*)\.([^\.]+)>/o) {
($user,$domain,$tld) = ($1,$2,$3);
print "$user $domain $tld\n";
$output = "$user\@$domain.$tld";
}
}

Ich hoffe, das hilft Dir weiter.
Gruss

Dirk


--
Please do not use the e-mail address devnull@fh-schmalkalden.de to contact
me, use the web interface at
http://www.fh-schmalkalden.de/url.php?/page/1026/select_wert /3023
instead. Thanks.

Re: Probleme mit Durchsuchen eines Strings

am 23.10.2007 13:41:54 von Daniel Krabbe

Am 23.10.2007 13:12 Uhr schrieb Dirk Krause
>
> while(<>)
> {
> $line = $_; chomp($line);
> if($line =~ /^[Tt][Oo]:[^<]*<([^\@]+)\@(.*)\.([^\.]+)>/o) {
> ($user,$domain,$tld) = ($1,$2,$3);
> print "$user $domain $tld\n";
> $output = "$user\@$domain.$tld";
> }
> }
>
> Ich hoffe, das hilft Dir weiter.

Hallo Dirk.
Danke dir erst einmal. Das hat mir insofern geholfen, dass jetzt zwar kein Fehler mehr
kommt, aber auch kein Ergebnis für die Adresse. Die Suche schient somit ins Leere zu laufen.

Hier nochmal das ursprüngliche Programm in einer Kurzform:

#!/usr/bin/perl
use strict;
use warnings;

my $header; #enthält die Headerzeilen, Einlesevorgang erspare ich euch ;-)
my $klaffe = "\@";
my $user;
my $domain;
my $tld;
my $testvar;

$header =~ /^To:\w*,?\w*?\r?\n$/m;
($user,$domain,$tld) = ($1,$2,$3);

$testvar = $user . $klaffe . $domain . $tld;

print "\n\n $testvar \n\n";

Die Ausgabe in diesem Fall für die einzelnen Variablen:

$user: Kompletten Header

$domain: Den Body, wenngleich der in $header nicht gespeichert ist...

$tld: Kein Inhalt




> Gruss
>
> Dirk
>

Gruß und Dank erstemal,
Daniel

Re: Probleme mit Durchsuchen eines Strings

am 23.10.2007 14:21:20 von Ulli Horlacher

Daniel Krabbe wrote:
> Ich komme einfach nicht weiter. Vielleicht hat ja noch jemand eine Idee. Egal welchen
> Ausdruck ich nutze, Ergebnis ist eine Fehlermeldung:
> Use of uninitialized value in concatenation (.) or string at
> /etc/postfix/scripts/guteidee3.pl line 208, chunk 1.
>
> Zeile 208 lautet:
> $testvar = $user . $klaffe . $domain . $tld;

Da war eine deiner Variablen undefiniert.

Kein Wunder bei:

> $header =~ /^To:\w*,?\w*?\r?\n$/m;
> ($user,$domain,$tld) = ($1,$2,$3);

Wenn deine $header nicht die regexp-Bedingungen erfuellt sind
$1,$2,$3 und damit $user,$domain,$tld undef.

Ich wuerde das wenigstens umformulieren auf:

if ($header =~ /^To:\w*,?\w*?\r?\n$/) {
($user,$domain,$tld) = ($1,$2,$3);
$testvar = $user . $klaffe . $domain . $tld;
}

Ansonsten:

> ==> To: test, user2

Matcht nicht. Da sind zuviele Spaces drin.

Ein passender match fuer dieses Beispiel waere:

/^To:\s*\w+,\w+\s*?/i

--
Ullrich Horlacher Informationssysteme und Serverbetrieb
Rechenzentrum E-Mail: horlacher@rus.uni-stuttgart.de
Universitaet Stuttgart Tel: ++49-711-685-65868
Allmandring 30 Fax: ++49-711-682357
70550 Stuttgart (Germany) WWW: http://www.rus.uni-stuttgart.de/

Re: Probleme mit Durchsuchen eines Strings

am 24.10.2007 17:38:37 von Helmut Wollmersdorfer

Ulli Horlacher wrote:
> Daniel Krabbe wrote:

> Ansonsten:
>
>> ==> To: test, user2
>
> Matcht nicht. Da sind zuviele Spaces drin.
>
> Ein passender match fuer dieses Beispiel waere:
>
> /^To:\s*\w+,\w+\s*?/i

Dsas würde auch nicht matchen, weil nach dem Komma auch noch ein \s*
hingehört.

Helmut Wollmersdorfer

Re: Probleme mit Durchsuchen eines Strings

am 24.10.2007 18:41:33 von Roman Racine

Daniel Krabbe wrote:

> Ich komme einfach nicht weiter. Vielleicht hat ja noch jemand eine Idee.
> Egal welchen Ausdruck ich nutze, Ergebnis ist eine Fehlermeldung:
> Use of uninitialized value in concatenation (.) or string at
> /etc/postfix/scripts/guteidee3.pl line 208, chunk 1.
>
> Zeile 208 lautet:
> $testvar = $user . $klaffe . $domain . $tld;
>
> Die vorhergehenden Zeilen:
>
> $header =~ /^To:\w*,?\w*?\r?\n$/m;
> ($user,$domain,$tld) = ($1,$2,$3);
>
> Oh man, ich hasse es.
>
> Hier mal ein Beispielheader, den ich durchsuche:
>
> Return-Path:
> Received: blabla1
> Received: blabla2
> Message-ID: <471A13F5.6070002@domain.tld>
> Date: Sat, 20 Oct 2007 16:43:01 +0200
> From: test, user
> User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.0.13)
> Gecko/20070809 Thunderbird/1.5.0.13 Mnenhy/0.7.5.0
> MIME-Version: 1.0
>
>
> ==> To: test, user2

Ich hab's gestern schon per Mail geschickt, aber zu Dokumentationszwecken,
falls es jemanden interessiert:

my ($name, $local, $domain, $tld);
$_ =~ /^To:\s+(?:"?([^<\"]+)"?\s)? (?:(.+)\.)?(.+?)>?(?:\s+\((.+?)\))?\r?\n$/x;
if (defined($5)) {
($name,$local,$domain,$tld) = ($5, $2, $3, $4);
} else {
($name,$local,$domain,$tld) = ($1, $2, $3, $4);
}
print "Name: $name\tlocal: $local\tdomain: $domain\t tld: $tld\n";

Das matcht:
To: Max Muster
To: "Max Muster"
To: Muster, Max
To: max@muster.example
To: max@muster.example (Max Muster)
To: max@example
To: max@subdomain.muster.example

Gruss

Roman°
--
IRC-Freenode: #usenet-friends
http://www.usenet-friends.ch.vu/