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.

<?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($url0, -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($url0, -1);
    }
    elseif(
$chr==='(' || $chr==='[' || $chr==='{'){
      
// öffnende Klammer am Ende gehört nicht zur URL
      
$afterUrl $chr.$afterUrl;
      
$url substr($url0, -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.

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.
 


Andere Einträge


Kommentare

#1
von Bruno am 10.09.2010
danke,!
genau das mit den klammern hab ich gesucht (:

#2
von Fixundfoxy am 23.01.2012
Das ist ein guter Ansatz mit den Klammern, Dankeschön!

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

#3
von Floern am 31.01.2012
Links mit Leerzeichen lassen sich schlicht nicht (oder nur sehr schwierig) automatisch erkennen. Hier wäre schon menschliche Intelligenz gefragt, weil nur ein Mensch sicher erkennen kann, ob ein Wort nach einem Leerzeichen noch zum Link gehört oder nicht.

#4
von Fixundfoxy am 06.02.2012
Hallo Floern,

vielen Dank für Deine Antwort!

MfG,

Fixundfoxy

#5
von en4ce am 09.02.2012
danke, super einfach, funktioniert bestens, klasse arbeit && danke fürs teilen! (sowas erspart unheimlich nerven und zeit)

grüße

#6
von Michael am 01.03.2012
Ich habe einen Fall "gefunden" der nicht erkannt wird. Twitter z.B. hat solche Links.
https://twitter.com/#!/seitexyz

Wie müsste man das Script anpassen?

#7
von PseudoPsycho am 15.04.2012
Hey, Michael!
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==='<')

#8
von Deen am 25.01.2014
Die Funktion ist fast perfekt, funktioniert aber nicht vollständig und kann einem teilweise ganze Inhalte zerhacken.

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?

#9
von prof am 24.05.2014
@Deen

wenn du eine negative assertation einbaust, stellt das kein problem mehr dar, sowohl bei "link" als auch bei <script...