Ik gebruik de volgende functie om een url te parsen in de reactiemogelijkheid op mijn site (de functie heb ik ergens geleend :)). Nu is het vervelende dat als de url te lang is mijn hele layout verneukt wordt. Iemand die onderstaande functie begrijpt? En aan kan geven hoe ik hem aan kan passen?
<?
function autolink($message)
{
$text = " " . $message;
$text = preg_replace("#([\n ])([a-z]+?)://([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+]+)#i", "\\1<a class='top2' href=\"\\2://\\3\" target=\"_blank\">\\2://\\3</a>", $text);
$text = preg_replace("#([\n ])www\.([a-z0-9\-]+)\.([a-z0-9\-.\~]+)((?:/[a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+]*)?)#i", "\\1<a class='top2' href=\"http://www.\\2.\\3\\4\"; target=\"_blank\">www.\\2.\\3\\4</a>", $text);

$text = substr($text, 1);
return($text);
}
?>
De eerste preg_replace deelt een absolute URL op in een 'scheme' (het gedeelte voor de ://, dus http, ftp, etc) en de bijbehorende 'reference' (het gedeelte na de ://, bijvoorbeeld www.phphulp.nl/forum/showtopic.php?cat=1&id=10676). Het scheme krijgt de referentie \\2 en de reference krijgt referentie \\3. De whitespace (newline of spatie) dir voor de url staat krijgt referentie \\1. Met behulp van die referenties wordt de hyperlink weer samengesteld.

De tweede preg_replace deelt een relatieve URL (die in dit geval met www. moet beginnen) op in een hostname (\\2), domainname (\\3) en path/query (\\4). In het geval van de URL die ik als voorbeeld heb genomen krijg je dan:

\\2 = phphulp
\\3 = nl
\\4 = /forum/showtopic.php?cat=1&id=10676

Overigens wordt het aanbevolen om $1 (etc) te gebruiken in plaats van \\1.

Op dit moment zou ik geen gemakkelijke manier weten om de URL in te korten. Het zou dan in de eerste preg_replace gaan om de tweede \\3 en in de tweede preg_replace om de tweede \\4. De eerste daarvan wil je niet inkorten, omdat dan je href ook wordt verminkt. Ik denk hier nog even over na.
Okay, ik denk dat het met callbacks wel moet kunnen gaan lukken. Ik heb het niet getest (dat mag jij doen ;-)) maar probeer het volgende eens:

<?
function make_url1($x)
{
$maxlen = 30;
$url = "{$x[2]}://{$x[3]}";
if (strlen($url) > $maxlen)
{
$url = substr_replace($url, '...', $maxlen-3);
}
return "{$x[1]}<a class='top2' href=\"{$x[2]}://{$x[3]}\" target=\"_blank\">$url</a>";
}

function make_url2($x)
{
$maxlen = 30;
$url = "www.{$x[2]}.{$x[3]}{$x[4]}";
if (strlen($url) > $maxlen)
{
$url = substr_replace($url, '...', $maxlen-3);
}
return "{$x[1]}<a class='top2' href=\"http://{$x[2]}.{$x[3]}{$x[4]}\" target=\"_blank\">$url</a>";
}

function autolink($message)
{
$text = " " . $message;
$text = preg_replace_callback("#([\n ])([a-z]+?)://([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+]+)#i", "make_url1", $text);
$text = preg_replace_callback("#([\n ])www\.([a-z0-9\-]+)\.([a-z0-9\-.\~]+)((?:/[a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+]*)?)#i", "make_url2", $text);

$text = substr($text, 1);
return($text);
}
?>

In de callback-functies wordt gekeken naar de lengte van de URL. Als die langer is dan 30 tekens (met dat getal moet je een beetje experimenteren) zal hij de eerste 27 tekens en 3 puntjes laten zien.
hoi Willem
bedankt voor de moeite die je hebt genomen om me uit te leggen wat de functie nu precies doet! Helaas werkt de oplossing die jij voorstelt niet :(. De functie zoals jij hem voorstelt doet precies hetzelfde als de functie die ik nu gebruik.
http://www.phphulp.nl/php/scripts/1/2/

ik wist dat ergens iets stond
dit is niet precies wat je bedoeld volgens mij maar het is goed te gebruiken denk ik

EDIT: [ vergeten
Oeps, er zaten nog twee foutjes in:

maxlen = 30 moet zijn: $maxlen = 30

En de substr_replace-regels moeten worden:

$url = substr_replace($url, '...', $maxlen-3);

Dan werkt 'ie wel (iig bij mij)
@Erik: De link die jij gaf, doet in principe hetzelfde als substr_replace(). Zonder een callback in je regular expression heb je er echter niets aan, omdat je anders je hyperlink gaat inkorten in plaats van alleen de string die op je beeldscherm komt.
wil je hetzelfde als wat phphulp heeft?
yep! geweldig Willem dat werkt. (ps die eerste fout had ik er uitgehaald, de tweede niet :P ).

Reageren