Как имитировать поведение автоматической привязки StackOverflow

С PHP, как я могу имитировать поведение автоматической привязки StackOverflow (какой BTW просто круто)?

Например, следующий URL:

http://www.stackoverflow.com/questions/1925455/how-to-mimic-stackoverflow-auto-link-behavior

Преобразуется в это:

<a title="how to mimic stackoverflow auto link behavior" rel="nofollow" href="http://www.stackoverflow.com/questions/1925455/how-to-mimic-stackoverflow-auto-link-behavior">stackoverflow.com/questions/1925455/…</a> 

В этом случае мне не нужен атрибут title .


И это:

http://pt.php.net/manual/en/function.base-convert.php#52450

Преобразуется в это:

 <a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php#52450">pt.php.net/manual/en/…</a> 

Как я могу сделать аналогичную функцию в PHP?

PS: Посмотрите мои комментарии по этому вопросу еще на несколько примеров и поведений.

Попробуйте это. Шаблон регулярного выражения, соответствующий URL-адресу, относится к Daring Fireball .

 /** * Replace links in text with html links * * @param string $text * @return string */ function auto_link_text($text) { // a more readably-formatted version of the pattern is on http://daringfireball.net/2010/07/improved_regex_for_matching_urls $pattern = '(?i)\b((?:[az][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][az]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”'']))'; $callback = create_function('$matches', ' $url = array_shift($matches); $url_parts = parse_url($url); $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH); $text = preg_replace("/^www./", "", $text); $last = -(strlen(strrchr($text, "/"))) + 1; if ($last < 0) { $text = substr($text, 0, $last) . "&hellip;"; } return sprintf(\'<a rel="nofollow" href="%s">%s</a>\', $url, $text); '); return preg_replace_callback($pattern, $callback, $text); } 

Текст ввода:

 This is my text. I wonder if you know about asking questions on StackOverflow: Check This out http://www.stackoverflow.com/questions/1925455/how-to-mimic-stackoverflow-auto-link-behavior Also, base_convert php function? http://pt.php.net/manual/en/function.base-convert.php#52450 http://pt.php.net/manual/en/function.base-convert.php?wtf=hehe#52450 

Выходной текст:

 This is my text. I wonder if you know about asking questions on StackOverflow: Check This out <a rel="nofollow" href="http://www.stackoverflow.com/questions/1925455/how-to-mimic-stackoverflow-auto-link-behavior">stackoverflow.com/questions/1925455/&hellip;</a> Also, base_convert php function? <a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php#52450">pt.php.net/manual/en/&hellip;</a> <a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php?wtf=hehe#52450">pt.php.net/manual/en/&hellip;</a> 

Это основано на том же регулярном выражении daringfireball.net , но добавляет немного больше логики, чем пример Эрика Коулмана, а также конфигурацию для максимальной глубины URL (например, SO 50), максимальная глубина пути при усечении URL-адреса (похоже, be 2) и символ многоточия ( &hellip; ).

Насколько я знаю, это повторяет все функции SO-перезаписи SO, по крайней мере, до того, что было обсуждено до сих пор в комментариях и ответах здесь.

 function auto_link_text($text) { $pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#'; return preg_replace_callback($pattern, 'auto_link_text_callback', $text); } function auto_link_text_callback($matches) { $max_url_length = 50; $max_depth_if_over_length = 2; $ellipsis = '&hellip;'; $url_full = $matches[0]; $url_short = ''; if (strlen($url_full) > $max_url_length) { $parts = parse_url($url_full); $url_short = $parts['scheme'] . '://' . preg_replace('/^www\./', '', $parts['host']) . '/'; $path_components = explode('/', trim($parts['path'], '/')); foreach ($path_components as $dir) { $url_string_components[] = $dir . '/'; } if (!empty($parts['query'])) { $url_string_components[] = '?' . $parts['query']; } if (!empty($parts['fragment'])) { $url_string_components[] = '#' . $parts['fragment']; } for ($k = 0; $k < count($url_string_components); $k++) { $curr_component = $url_string_components[$k]; if ($k >= $max_depth_if_over_length || strlen($url_short) + strlen($curr_component) > $max_url_length) { if ($k == 0 && strlen($url_short) < $max_url_length) { // Always show a portion of first directory $url_short .= substr($curr_component, 0, $max_url_length - strlen($url_short)); } $url_short .= $ellipsis; break; } $url_short .= $curr_component; } } else { $url_short = $url_full; } return "<a rel=\"nofollow\" href=\"$url_full\">$url_short</a>"; } 

Пример ввода:

 This is my text. I wonder if you know about asking questions on StackOverflow: Check This out http://www.stackoverflow.com/questions/1925455/how-to-mimic-stackoverflow-auto-link-behavior Also, base_convert php function? http://pt.php.net/manual/en/function.base-convert.php#52450 http://pt.php.net/manual/en/function.base-convert.php?wtf=hehe#52450 http://ab/c/d/e/f/test and http://ab/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/z/y/w/z/test 

Результат выборки:

 This is my text. I wonder if you know about asking questions on StackOverflow: Check This out <a rel="nofollow" href="http://www.stackoverflow.com/questions/1925455/how-to-mimic-stackoverflow-auto-link-behavior">http://stackoverflow.com/questions/1925455/&hellip;</a> Also, base_convert php function? <a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php#52450">http://pt.php.net/manual/en/&hellip;</a> <a rel="nofollow" href="http://pt.php.net/manual/en/function.base-convert.php?wtf=hehe#52450">http://pt.php.net/manual/en/&hellip;</a> <a rel="nofollow" href="http://ab/c/d/e/f/test">http://ab/c/d/e/f/test</a> and <a rel="nofollow" href="http://ab/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/z/y/w/z/test">http://ab/c/d/&hellip;</a> 

Это преобразует образец строки в то, что вам нужно. Я оставил title поскольку оно исходит из другого источника, а не только автономного URL-адреса, и вы сказали, что это не важно.

 <?php $urlInput="http://www.stackoverflow.com/questions/1925455/how-to-mimic-stackoverflow-auto-link-behavior"; preg_match('@http://(?:www\.)?(\S+/)\S*(?:\s|$)@i', $urlInput, $matches); print('<a rel="nofollow" href="' . trim($matches[0]) . '">' . $matches[1] . '...</a>'); ?> 

При необходимости просканируйте текст.

Если вы хотите сопоставить только определенное количество элементов URL-адреса, используйте этот RE:

 '@http://(?:www\.)?((?:\S+?/){1,3})\S*(?:\s|$)@i' 

Это позволит извлечь до 3 элементов пути (хост и до двух каталогов). Вы можете изменить верхнюю границу в {1,3} чтобы определить максимальное количество элементов пути, которые вы хотите.

Изменен окончание \S чтобы разрешить нулевые совпадения.

Если у вас есть предсказуемый URL-адрес, такой как SO, вам должно быть легко схватить ссылки с регулярным выражением и отфильтровать те, которые соответствуют шаблону. Поэтому, если ваш URL-адрес – http://example.com/stuff/1234 то поиск http://example.com/stuff/1234/how-to-mimic будет довольно тривиальным с регулярным выражением.

 <?php preg_match('/http:\/\/example.com\/(\w*)\/(\d)[\/*]/', $text, $matches); if (is_array($matches)) { foreach ($matches as $match) { // do something... } } ?> 

Несколько основанный на ответе Кевина Брока, но позволяет настраивать параметры (глубину и длину папки) и принимает URL-адреса без привязки косых черт:

 $url = 'http://www.stackoverflow.com/questions/1925455/how-to-mimic-stackoverflow-auto-link-behavior'; $output = ''; $params = array ( 'length' => 10, 'depth' => 2, ); preg_match ('@http://(?:www\.)?([^/?# ]+)(/\S+)?(?=\s|$)@i', $url, $matches); if (isset ($matches[2])) { $parts = explode('/', substr($matches[2], 1)); if (count($parts) > $params['depth'] && strlen($matches[1].$matches[2]) > $params['length']) $output = $matches[1].'/'.implode('/', array_slice($parts, 0, 2)).'/...'; else $output = $matches[1].$matches[2]; } else $output = $matches[1]; echo '<a href="'.$matches[0].'">'.$output.'</a>'; 

Надеюсь это поможет

См. Regex (регулярное выражение) для соответствия URL-адресу :

 https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)? 

PHP Пример. Автоматически связывать внутренний текст URL.

 $text = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)@', '<a href="$1">$1</a>', $text);