Письмо:
Помогите, пожалуйста, справиться с данной задачей. Постараюсь объяснить как можно подробнее. Я разрабатываю поисковую систему и мне нужно наглядно предоставить информацию в результатах поиска. Под каждым результатом имеется текст, адрес страницы, на которую будут переходить. Обычно в поисковиках этот текст (ссылка) написан зеленым цветом.
Допустим, под результатами будет длинная ссылка, например:
http://lphp.ru/rus/novosti/electronic/tec/news/category/computers.html.
Согласитесь, что неудобно смотреть, куда ведет эта ссылка. Поэтому, можно ее обрезать с конца. Вот пример (он показан в "Листинг № 6" на странице http://lphp.ru/?id_article=150):
//если длинна строки $url длиннее $dlina
if(strlen($url)>$dlina)
{
//оставляем кусочек в $dlina символов
$newurl = substr($url, 0, $dlina);
echo $newurl.'...';
}
В результате из
http://lphp.ru/rus/novosti/electronic/tec/news/category/computers.html
получим:
http://lphp.ru/rus/novo....
Но это выглядит как-то некрасиво.
Вопрос:
Как сократить адрес длинной ссылки не с конца и не с начала, а в середине?
Например:
Из
http://lphp.ru/rus/novosti/electronic/tec/news/category/computers.html
станет
http://lphp.ru/.../category/computers.html
так уже понятнее
То есть, адрес сайта остался (http://lphp.ru/), осталось название файла (/computers.html) и последняя папка (/category), а вот все остальное заменилось многоточием (...).
Ответ:
Листинг № 1 - Регулярное выражение укорачивает URL
<?php
$url = "http:⁄⁄lphp.ru/rus/novosti/electronic/tec/news/category/computers.html";
$p = "|(http:⁄⁄[-a-z0-9]+(\.[-a-z0-9]+)*\.(com;edu;info;ru;su;org;biz;net))?(/)(?:([-a-z0-9]+\/)*)(?=([-a-z0-9]+/))|";
$c = preg_replace($p,"/.../",$url);
echo "<a href=".$url." target='_blank'>".$c."</a>";
/*
Выведет на монитор:
http:⁄⁄lphp.ru/.../category/computers.html
*/
?>
Во второй строке кода листинг №1. Домены первого уровня можно добавлять (com;edu;info;ru; .... и т.д.)
Листинг № 2 - Более универсальный пример, сокращает различные URL.
<?php
$url = "http:⁄⁄lphp.ru/12-DJ!?/for~ele-4/dir.8/index.asp";
$p =
"|(http:⁄⁄[-a-z0-9]+(\.[-a-z0-9]+)*\.(com;edu;info;ru;su;org;biz;net))?(?:(/[-a-zA-Z0-9_~!?=&%]+)*)(?=/([-a-zA-Z0-9_~\.!?=&%]*)?/([-a-zA-Z0-9\.~!?=%&_]*)?$)|";
$c = preg_replace($p,"..",$url);
echo "<a href=".$url." target='_blank'>".$c."</a>";
?>
Вариант представленный в листинге 2 более функционален и спокойно справится с различными ссылками, пример ссылок представлен ниже.
http://lphp.ru/rus/news/category/computers.html,
http://lphp.ru/docs/RUS/php42/f/substr-count.html,
http://doc.lphp.ru/php/ru/function.substr-count.html,
http://www3.lphp.ru/~radigin/docs/PHP/function.substr-count.html,
http://www.lphp.ru/webwide/layer.php,
http://lphp.ru/12-DJ!?/for~ele-4/dir.8/index.asp,
http://lphp.ru/postget/test/dir/page,
http://lphp.ru/postget/test/dir/
Русские буквы в URL не будут работать, впрочем как и некоторые знаки и некоторые URL.
Вариант на десерт
Здесь не используются регулярные выражения, а работает функция, которая принимает строку URL и возвращает отформатированную строку согласно условию.
Листинг № 3 - Форматируем URL
<?php
function m($r)
{
// $r - принимает URL-адрес
$x = 5; // кол-во ключей массива
$arr = explode("/", $r);
if(count($arr) <= $x) return $r;
$ar = array(); // создаём пустой массив
if($arr[0] == "http:" && $arr[1] == "")
{
while(count($arr) > $x)
{
$s = array_pop($arr); // извлекаем последнее значение
array_push ($ar, $s); // добавляем в новый массив
if(count($ar) > 1)
{
return $arr[0]."//".$arr[2]."/.../".$ar[1]."/".$ar[0]; // на выходе даёт обрезанный URL
}
}
}
else
{
return "not url";
}
}
$r = "http:⁄⁄lphp.ru/rus/novosti/electronic/tec/news/category/computers.html";
echo m($r); // http:⁄⁄lphp.ru/.../category/computers.html
?>
Урок закончен.