Alle Mailadressen ersetzen
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
adresse
code
email
ersetzen
header
input
match
muster
output
problem
server
stehen
stelle
string
tag
text
type
umwandlung
url
vorkommen
-
Moin,
ich habe gerade mal wieder ein kleines Denktag/problem">problem. Ich möchte alle E-Mail Adressen im Format
<a href="mailto:foo@bar.tld">foo@bar.tld</a>
wie folgt ersetzen:
<a href="mailto:foo@bar.tld"><span class="bla">foo@bar.tld</span></a>
Leider stelle ich mich an dieser Stelle etwas blöd an, da ich nicht nur die Mailadresse zwischen den Tags ersetze, sondern auch die innerhalb, was natürlich nicht Sinn der Sache ist.
Kennt wer eine elegante Lösung, um alle Mailadressen im o.g. Format zu finden und wie gewünscht zu ersetzen? Allein mein Regex sieht unnormal aus :/ -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
ich hätte im Script die richtige Stelle gesucht und den span Tag dort eingesetzt. Alle mal einfacher und vor allem Ressourcen schonender.
-
Das geht nicht ohne Weiteres, sonst hätte ich es bereits so gemacht :)
-
Hallo
also da gäbe es schon durchaus möglichkeiten das um zu setzen
du könntest Beispielsweise mit php die Datei welche verändert werden soll in einen String laden und dann mit preg_replace
das zu verändernde raus suchen und parralel ersetzen und dann das Ergebnis wieder in die Datei schreiben
Gruß
BeikaSounds -
Und wenn du zuerst strip_tags() ausführst und dann den Link wieder zusammenbaust?
Würde ich machen, bevor ich mit Regex anfange. -
$alt='<a href="mailto:user@server.tld">sende ein mail</a>'; $prefix='<span class="bla">'; $postfix='</span>'; $muster="~(<a .*?href=[\'|\"]mailto:.*?[\'|\"].*?>)(.*?)(</a>)~"; $neu=preg_replace($muster,"$1$prefix$2$postfix$3", $alt); echo $neu;
oder so ähnlich? -
xian schrieb:
^
$alt='<a href="mailto:user@server.tld">sende ein mail</a>'; $prefix='<span class="bla">'; $postfix='</span>'; $muster="~(<a .*?href=[\'|\"]mailto:.*?[\'|\"].*?>)(.*?)(</a>)~"; $neu=preg_replace($muster,"$1$prefix$2$postfix$3", $alt); echo $neu;
oder so ähnlich?
Danke, funzt :) War ein Denkfehler von mir :) -
wenn man nur die empfängeradresse (steht in $1) weiterverwenden will:
$muster="~<a .*?href=[\'|\"]mailto:(.*?)[\'|\"].*?\>.*?</a>~";
oder alles ($1 = <a>-tag inkl. adresse, $2 = nur adresse, $3 = text des links, $4 = </a>):
$muster="~(<a .*?href=[\'|\"]mailto:(.*?)[\'|\"].*?\>)(.*?)(</a>)~";
das nächste geklammerte landet immer unter der nächsten nummer, auch geschachtelt. -
Danke. Aufgrund gewisser Schwierigkeiten, habe ich mich nun für DOMDocument entschieden. Aber auch hier habe ich ein großes Problem:
<?php libxml_use_internal_errors(true); // ignore malformed HTML $xml = new DOMDocument(); $xml->loadXML('<a href="mailto:foo@bar.tld">foo@bar.tld</a>'); foreach($xml->getElementsByTagName('a') as $link) { if(strpos($link->getAttribute('href'), 'mailto:') === 0) { $newhref = 'x.php?a=' . str_replace('mailto:', '', $link->getAttribute('href')); $link->setAttribute('href', $newhref); } $link->nodeValue = preg_replace_callback('/[!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~]*(?:\\[\x00-\x7F][!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~]*)*(?:\.[!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~]*(?:\\[\x00-\x7F][!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~]*)*)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*\.[a-z]{2,}/', function($matches) { return '<span class="bla">' . $matches[0] . '</span>'; }, $link->nodeValue); } $string = $xml->saveHTML(); echo $string;
Grundsätzlich funktioniert das. Dummerweise jedoch wird bei meinem preg_replace_callback der Code in htmlentities umgewandelt. Das ist zwar richtig, aber nicht gewollt :D Mir fehlt es gerade an der Idee, das Problem zu beheben, sodass am Ende genau das raus kommt, was ich erwarte.
Beitrag zuletzt geändert: 1.2.2013 4:38:37 von fabo -
die umkehrung zu htmlentities() wäre html_entity_decode().
was erwartest du denn, dass am ende herauskommt? -
html_entity_decode ist klar, löst aber das Problem nicht.
Raus kommt:
<a href="x.php?a=foo@bar.tld"><span class="bla">dlt.rab@oof</span></a>
Raus kommen soll:
<a href="x.php?a=foo@bar.tld"><span class="bla">dlt.rab@oof</span></a>
Code:
<?php libxml_use_internal_errors(true); // ignore malformed HTML $xml = new DOMDocument(); $xml->loadXML('<a href="mailto:foo@bar.tld">foo@bar.tld</a>'); foreach($xml->getElementsByTagName('a') as $link) { if(strpos($link->getAttribute('href'), 'mailto:') === 0) { $newhref = 'x.php?a=' . str_replace('mailto:', '', $link->getAttribute('href')); $link->setAttribute('href', $newhref); } $link->nodeValue = preg_replace_callback('/[!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~]*(?:\\[\x00-\x7F][!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~]*)*(?:\.[!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~]*(?:\\[\x00-\x7F][!#\$%&\'\*\+\-\/0-9=\?a-z\^_`\{\}\|~]*)*)*@[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)*\.[a-z]{2,}/', function($matches) { return '<span class="bla">' . strrev($matches[0]) . '</span>'; }, $link->nodeValue); } $string = $xml->saveHTML(); echo $string;
Vielleicht erkläre ich noch einmal kurz mein Vorhaben:
Ich möchte in einem HTML-Quelltext alle Hyperlinks finden, die einen mailto-Link enthalten. Diesen mailto-Link möchte ich durch einen normalen Hyperlink ersetzen (d.h. mailto: ersetzen durch x.php?a= und die Mailadresse in base64 umwandeln) und eine eventuell enthaltene Mailadresse im Content des Hyperlinks möchte ich umdrehen (dafür strrev()). Alles Andere, d.h. Bilder, usw. was sich noch im Content des Hyperlinks befindet, soll dort auch- unverändert bleiben.
Beispiel
Aus
<a href="mailto:foo@bar.tld">foo@bar.tld</a>
soll werden:
<a href="x.php?a=Zm9vQGJhci50bGQ">dlt.rab@oof</a>
Und aus
<a href="mailto:foo@bar.tld">Hallo World foo@bar.tld <img src="bild.ext" /></a>
soll werden:
<a href="x.php?a=Zm9vQGJhci50bGQ">Hallo World dlt.rab@oof <img src="bild.ext" /></a>
Wogegen aus
<a href="mailto:foo@bar.tld">Email</a>
werden soll:
<a href="x.php?a=Zm9vQGJhci50bGQ">Email</a>
-
wegen server-down ungetestet: $2 für base64, $5 für strrev, (die andern in der reiherfolge).
$muster="~(<a .*?href=[\'|\"]mailto:)(.*?)([\'|\"].*?\>)(.*?)(\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}\b)(.*?</a>)~i";
-
Sobald im Text etwas anderes als eine Mailadresse steht, geht leider nüscht mehr :/
EDIT:
(<a .*?href=[\'|\"]mailto:)(.*?)([\'|\"].*?\>)(.*?)(\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}\b)?(.*?</a>)
So scheint es zu gehen. Mal rumprobieren :)
Beitrag zuletzt geändert: 2.2.2013 0:05:15 von fabo -
ok. du darfst hinter ) auch ein ? setzten, zb:
... (\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}\b)? ...
mensch, kann uns denn hier niemand helfen? -
Das mit dem Fragezeichen hatte ich bemerkt (siehe Edit). Funzt aber leider noch nicht so ganz :D
Array ( [0] => <a href="mailto:user@server.tld">sende eine mail an user@server.tld</a> [1] => <a href="mailto: [2] => user@server.tld [3] => "> [4] => [5] => [6] => sende eine mail an user@server.tld</a> )
EDIT:
Ich verstehe das Problem nur nicht... Alles Mögliche ausprobiert mit dem Ergebnis, dass durch das ? nach der Klammer funktioniert, wenn keine Mailadresse enthalten ist und ohne ? nach der Klammer nur mit Mailadresse im Text funktioniert. So etwas blödes ist mir auch noch nicht untergekommen ^^
Beitrag zuletzt geändert: 2.2.2013 0:22:58 von fabo -
Hoffentlich habe ich das so richtig verstanden… das ganze ohne DOMDocument, aber es darf deshalb auch keine verschachtelten A-Tags geben.
<?php header('content-type: text/plain'); $input = <<< ETX <a href="mailto:foo@bar.tld">foo@bar.tld</a> <a href="mailto:foo@bar.tld">Hallo World foo@bar.tld <img src="bild.ext" /></a> <a href="mailto:foo@bar.tld">Email</a> ETX; $regex = '/<a .*href=([\'"])mailto:(.+)\\1[^>]*>(.*)<\/a>/U'; function callback($match) { $b64 = base64_encode($match[2]); $content = str_replace($match[2], strrev($match[2]), $match[3]); return "<a href=\"x.php?a=$b64\">$content</a>"; } $output = preg_replace_callback($regex, 'callback', $input); echo(<<< ETX INPUT: $input ==== OUTPUT: $output ETX );
Ausgabe:INPUT: <a href="mailto:foo@bar.tld">foo@bar.tld</a> <a href="mailto:foo@bar.tld">Hallo World foo@bar.tld <img src="bild.ext" /></a> <a href="mailto:foo@bar.tld">Email</a> ==== OUTPUT: <a href="x.php?a=Zm9vQGJhci50bGQ=">dlt.rab@oof</a> <a href="x.php?a=Zm9vQGJhci50bGQ=">Hallo World dlt.rab@oof <img src="bild.ext" /></a> <a href="x.php?a=Zm9vQGJhci50bGQ=">Email</a>
Online-Demo -
Ach komm schon. Das ist doch ein Witz, oder? Zwei Tage bekommt man hier nix zu Stande und dann kommst du und machst sowas <.<
Aber deswegen mag ich dich :D Danke dir. Hoffen wir, dass das so klappt, wie ich mir das vorstelle.
DOMDocument war nur so ein Gedanke, weil's mit dem ursprünglichen Regex nicht so klappte, wie es sollte. Zudem meine ich, dass DOMDocument schneller ist als Regex.
Bei deinem Regex habe ich ziemlich schnell die Übersicht verloren :S Aber davon ab... Irgendeine Ahnung, warum der Regex von xian sich verhält, wie er sich verhält?! Mir erschließt sich das Problem nach wie vor nicht.
@xian
Vielen Dank für deine Geduld :)
EDIT:
Okay... Höherer Schwierigkeitsgrad :D In deinem Vorschlag wird vorausgesetzt, dass die Mailadresse, die im mailto steht, auch im Linkcontent enthalten sein muss.
Was aber, wenn's so aussieht:
<a href="mailto:foo@bar.tld">bar@foo.tld</a>
Spätestens dann haben wir wieder ein kleines Problem.
Beitrag zuletzt geändert: 2.2.2013 10:40:50 von fabo -
fabo schrieb:
OK, ich habe angenommen, dass nur die Mail-Adresse aus dem
In deinem Vorschlag wird vorausgesetzt, dass die Mailadresse, die im mailto steht, auch im Linkcontent enthalten sein muss.
Was aber, wenn's so aussieht:
Spätestens dann haben wir wieder ein kleines Problem.<a href="mailto:foo@bar.tld">bar@foo.tld</a>
"geschützt" werden soll… ansonsten wirst du 2 regex brauchen.mailto:
Hier eine vollständige Version, die aus mailto-Links deine Links macht und alle Mail-Adressen im Content umdreht, auch wenn das vermutlich nicht die beste Lösung ist:<?php header('content-type: text/plain'); $input = <<< ETX <a href="mailto:foo@bar.tld">foo@bar.tld</a> <a href="mailto:foo@bar.tld">Hallo World foo@bar.tld <img src="bild.ext" /></a> <a href="mailto:foo@bar.tld">Email</a> <a href="mailto:foo@bar.tld">bar@foo.tld</a> <a class="bla" href="mailto:foo@bar.tld" title="xyz">bar@foo.tld</a> ETX; $regex = '/<a (.*)href=([\'"])mailto:(.+)\\2([^>]*)>(.*)<\/a>/U'; $mail = '/\\b[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}\\b/'; function emailcallback($match) { return strrev($match[0]); } function callback($match) { global $mail; $b64 = base64_encode($match[3]); $content = preg_replace_callback($mail, 'emailcallback', $match[5]); return "<a {$match[1]}href=\"x.php?a=$b64\"{$match[4]}>$content</a>"; } $output = preg_replace_callback($regex, 'callback', $input); echo(<<< ETX INPUT: $input ==== OUTPUT: $output ETX );
Ausgabe:
Hoffentlich ist es jetzt das was du gesucht hast…INPUT: <a href="mailto:foo@bar.tld">foo@bar.tld</a> <a href="mailto:foo@bar.tld">Hallo World foo@bar.tld <img src="bild.ext" /></a> <a href="mailto:foo@bar.tld">Email</a> <a href="mailto:foo@bar.tld">bar@foo.tld</a> <a class="bla" href="mailto:foo@bar.tld" title="xyz">bar@foo.tld</a> ==== OUTPUT: <a href="x.php?a=Zm9vQGJhci50bGQ=">dlt.rab@oof</a> <a href="x.php?a=Zm9vQGJhci50bGQ=">Hallo World dlt.rab@oof <img src="bild.ext" /></a> <a href="x.php?a=Zm9vQGJhci50bGQ=">Email</a> <a href="x.php?a=Zm9vQGJhci50bGQ=">dlt.oof@rab</a> <a class="bla" href="x.php?a=Zm9vQGJhci50bGQ=" title="xyz">dlt.oof@rab</a>
-
Was soll ich noch sagen... Perfekt! Danke dir :)
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage