Hallo Wolfgang!
Mmh... hast Du diesen Code getestet? Irgendwie finde ich ihn recht seltsam, und die Ergebnisse, die er liefert, sind vermutlich nicht das, was Du Dir erhofft hast.
Also von vorn: Ich nehme an, Du willst eine Liste aller Mails eines Dokuments erstellen, wobei jeder Eintrag das Format "AddresseLinktext" hat. Ich habe es mal mit http://www.teamone.de/selfaktuell/e-woerter.htm (interessanter Artikel uebrigens) ausprobiert, und das Ergebnis ist:
Kess@topmail.de
muenz@compuserve.com
Stefan Münz, muenz@csi.com
while ($parselink_text =~ /<a\s*(.*?)mailto:([\w.-]+@[\w.-]+)(?:["'\s]?)\s*(.*?)>(.*?)</a>/si) {
$parselink_text = $';
$parselink_host = $4;
$parselink_host =~ s/<([^>]\s+)*>//g;
$parselink_host =~ s/\s+/ /g;
$parselink_host =~ s/^\s+//g;
push(@parselink_liste, "$2$parselink_host");
}
Einige Dinge, die mir aufgefallen sind:
Warum machst Du soviele Klammern, wenn Du hinterher die Haelfte der erzeugten Backreferences nicht benutzt? Warum schreibst Du (?:["'\s]?) und nicht einfach ["'\s]? ? Ist Dir klar, dass das $2 zum Zeipunkt des push nicht mehr die Mailadresse enthaelt, weil es in der dritten Zeile der Schleife undef wird? Uebrigens, die perlvar manpage sagt, dass die Benutzung der Variablen $`, $' und $& nicht zu vernachlaessigende Performanceeinbussen nach sich zieht.
Ich wuerde erstmal alle relavanten Teile mit
@all = ($parselink_text =~ /<a\s.*?mailto:([\w.-]+@[\w.-]+).*?>(.*?)</a>/gsi);
extrahieren. In @all steht dann abwechselnd die Email und der Linktext, letzterer jedoch noch mit voller Markup-Ausstattung. Um jetzt die Form "AddresseLinktext" zu bekommen, kommt man imho um eine Schleife nicht herum. Auch um die Ersetzung s/\s+/ /g; vorzunehmen, braucht man meines Erachtens eine Schleife (naja, man koennte den Ausdruck vielleicht auch vorher auf den gesamten Text anwenden). Die Ersetzungen s/<([^>]\s+)*>//g; (die ich einfach mal auf s/<.*?>//g; reduziert habe) und s/^\s//g; dagegen koennte man in den oben genannten RegExp einbauen, wenn man annimmt, dass der Linktext zwar durch Markup eingeschlossen ist, jedoch nicht davon unterbrochen wird (also sowas wie Link<BR>text nicht vorkommt).
Also zwei Vorschlaege, um die Pipe-Darstellung zu erreichen:
$x = '';
for (@all) {
$x or ($x = $_, next);
s/<.*?>//g;
s/\s+/ /g;
s/^\s//g;
push(@pairs, $x.''.$_);
$x = '';
}
Oder wenn Du es etwas more hardcore magst:
push(@pairs, shift(@all) . '' . do {for ($all[0]) {s/<.*?>//g; s/\s+/ /g; s/^\s//g}; shift(@all)}) while (@all);
Konkret würde ich gern die while-Schleife weghaben...Also das die Email-Adressen und deren Bezeichner gleich in einem Feld geschrieben werden...
»»
Na, wer knackt die Nuss?
Leider nicht geknackt, aber trotzdem ganz amuesant. :-)
Calocybe
P.S. Fuer's Archiv: Leider entfernt der Schwanzabschneider die Pipe-Zeichen (der vertikale Strich), die hier drin vorkommen. Koennte also stellenweise etwas sinnlos wirken.