URL im Text intelligent erkennen
Juni 2010
Ein oft zu beobachtendes Problem ist die automatische Verlinkung von URLs in Texten wie Posts in Foren oder Kommentare in Blog. Ein Komma nach dem Link wird gerne mal als Teil der URL interpretiert und bei einer Klammer, die eigentlich zur URL gehört wird der Link ungewollt abgeschnitten.
Allerdings lässt sich dieses Problem einfach beheben, in dem man die URLs im Text analysiert bevor man den Link setzt. Die Callback-Funktion findUrl() übernimmt diese Aufgabe.
Aufgerufen wird die Funktion über preg_replace_callback(), welche gleichzeitig die Ersetzung der Text-URL durch HTML-Code vornimmt:
Beispiele mit normalem Ersetzen. Der verlinkte Abschnitt ist unterstrichen.
Mit der obigen Analyse-Funktion werden die URLs nun aber wie folgt verlinkt:
Allerdings lässt sich dieses Problem einfach beheben, in dem man die URLs im Text analysiert bevor man den Link setzt. Die Callback-Funktion findUrl() übernimmt diese Aufgabe.
<?php
function findUrl($u){
$url = $u[0];
$afterUrl = ''; // Zeichenkette am Ende der URL, die nicht zur URL gehört
while(preg_match('#[[:punct:]]$#', $url, $found)){
$chr = $found[0]; // letztes Zeichen
if($chr==='.' || $chr===',' || $chr==='!' || $chr==='?' || $chr===':' || $chr===';' || $chr==='>' || $chr==='<'){
// Ein Satzzeichen, das nicht zur URL gehört
$afterUrl = $chr.$afterUrl;
$url = substr($url, 0, -1);
}
elseif($chr===')' && strpos($url, '(')!==false || $chr===']' && strpos($url, '[')!==false || $chr==='}' && strpos($url, '{')!==false)
break; // Klammer gehört nur zur URL, wenn auch öffnende Klammer vorkommt.
elseif($chr===')' || $chr===']' || $chr==='}'){
// .. Klammer gehört nicht zur URL
$afterUrl = $chr.$afterUrl;
$url = substr($url, 0, -1);
}
elseif($chr==='(' || $chr==='[' || $chr==='{'){
// öffnende Klammer am Ende gehört nicht zur URL
$afterUrl = $chr.$afterUrl;
$url = substr($url, 0, -1);
}
else
break; // Zeichen gehört zur URL
}
// URL mit HTML-Code zurückgeben
return '<a href="'.$url.'" title="'.str_replace('http://', '', $url).'">'.$url.'</a>'.$afterUrl;
}
?>
Aufgerufen wird die Funktion über preg_replace_callback(), welche gleichzeitig die Ersetzung der Text-URL durch HTML-Code vornimmt:
<?php
// Alle URLs in $text erfassen und an findUrl() übergeben
$text = preg_replace_callback('#https?://[^/\s]{4,}(/[^\s]*)?#s', 'findUrl', $text);
?>
In obiger Funktion werden nur HTTP- und HTTPS-URLs erfasst. Im Grunde liesse sich es auch auf FTP oder andere Protokolle ausweiten.Beispiele mit normalem Ersetzen. Der verlinkte Abschnitt ist unterstrichen.
Das ist die Kurz-URL http://goo.gl/vGNV, die auf http://de.wikipedia.org/wiki/Iron_Man_(Film) verweist.
(Mehr Infos unter http://www.ironman-derfilm.de/)
Alle drei Links sind ungültig. Beim ersten wird das Komma mit genommen, beim zweiten fliegt die Klammer weg, beim dritten wird wiederum eine Klammer zuviel genommen.(Mehr Infos unter http://www.ironman-derfilm.de/)
Mit der obigen Analyse-Funktion werden die URLs nun aber wie folgt verlinkt:
Das ist die Kurz-URL http://goo.gl/vGNV, die auf http://de.wikipedia.org/wiki/Iron_Man_(Film) verweist.
(Mehr Infos unter http://www.ironman-derfilm.de/)
Hier werden keine Satzzeichen zu viel erwischt, jedoch fliegt die Klammer nicht weg, wenn sie es nicht sollte.
(Mehr Infos unter http://www.ironman-derfilm.de/)

Andere Einträge
- strtocamelcase() - CamelCase
- href und URL zusammensetzen
- Array-Zeiger auf bestimmten Key setzen
- array_unique() für multidimensionale Arrays
- is_utf8() – auf UTF-8 prüfen
genau das mit den klammern hab ich gesucht (:
Dennoch hätte ich eine frage:
Was mache ich wenn ein User einen Link mit Leerzeichen veröffentlicht?
Beispiel:
http://www.example.com/das ist klasse/bitte lesen.txt
Spättestens bei "http://www.example.com/ist" wäre schluss mit dem Link.
Leerzeichen sind zwar in Links nicht erlaubt aber man findet sie immer öfter! Urlencode oder Rawurlencode könnten da ja Helfen aber wie bekomme ich das mit eurem Script hin?
Danke für die Antwort!!!
MfG,
Fixundfoxy
vielen Dank für Deine Antwort!
MfG,
Fixundfoxy
grüße
https://twitter.com/#!/seitexyz
Wie müsste man das Script anpassen?
Du musst glaube ich in der Abfrage:
if($chr==='.' || $chr===',' || $chr==='!' || $chr==='?' || $chr===':' || $chr===';' || $chr==='>' || $chr==='<')
den Teil mit dem Ausrufezeichen entfernen, also nur das:
if($chr==='.' || $chr===',' || $chr==='?' || $chr===':' || $chr===';' || $chr==='>' || $chr==='<')
Und zwar dann, wenn man z.B. einen Text hat der Code enthält oder einfach eine URL die in Anführungszeichen gesetzt ist. Sei es "http://www.link.de" oder <script type="text/javascript" src="http://www.link.de/file.js"></script>;
Bei ersterem verlinkt es das hintere " mit, beim zweiten sogar auch noch das "></script>
Wie müsste man die Funktion anpassen, dass das noch abgefangen wird? Also dass bei einem " aufgehört wird?
wenn du eine negative assertation einbaust, stellt das kein problem mehr dar, sowohl bei "link" als auch bei <script...