2011-03-17 8 views
19

chcę:Najlepszy sposób, aby linki klikalne w bloku tekstu

Here is link: http://google.com 
And http://example.com inside. 
And another one at the very end: http://test.net 

stać:

Here is link: <a href="http://google.com">http://google.com</a> 
And <a href="http://example.com">http://example.com</a> inside. 
And another one at the very end: <a href="http://test.net">http://test.net</a> 

Wydaje się to banalne zadanie, ale nie mogę znajdź działającą funkcję PHP. Czy masz jakies pomysły?

function make_links_clickable($text){ 
    // ??? 
} 

$text = 'Here is link: http://google.com 
And http://example.com inside. 
And another one at the very end: http://test.net'; 

echo make_links_clickable($text); 
+0

Duplikat pytania; Zobacz na http://stackoverflow.com/questions/5282745/simple-wiki-parser-and-link-autodetection – Akarun

+0

Możliwy duplikat [Zamień adresy URL w tekście za pomocą linków HTML] (http://stackoverflow.com/questions/1188129/replace-urls-in-text-with-html-links) – cweiske

Odpowiedz

45

Użyj tego (współpracuje z FTP, HTTP, FTPS i HTTPS programy):

function make_links_clickable($text){ 
    return preg_replace('!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()[email protected]:%_+.~#?&;//=]+)!i', '<a href="$1">$1</a>', $text); 
} 
+0

jakie są "!" Umieszczane na początku i końcu wyrażenia regularnego? –

+0

! = Wzór (aby zastąpić) "zacznij od" ... – Akarun

+0

Jakie są znaki spoza ASCII w twoim wyrobie regularnym? ("я" i "Я")? –

6

Spróbuj czegoś takiego:

function make_links_clickable($text) 
{ 
    return preg_replace ('/http:\/\/[^\s]+/i', "<a href=\"${0}\">${0}</a>", $text); 
} 

$result = make_links_clickable($text); 
+1

a co z XSS? –

+0

Rozwiązania zawarte w odsyłaczach sugerowanych przez Akarun i Lawrenca Cherone są bardziej kompletne, ponieważ sprawdzają adres URL pod kątem poprawnego adresu URL, wykrywają również łącza https i ftp, a przed wyświetleniem wyświetlają odnośniki urdecode. Moje rozwiązanie jest bardziej brudne, ale powinno działać w prostych zadaniach. –

5

należy odnieść się do tej odpowiedzi Replace URLs in text with HTML links

+0

A także sprawdź następujące zasoby, aby uzyskać więcej informacji na temat "Linkifying" URL (Podpowiedź: istnieje garść "gotchas"): [Problem z adresami URL] (http://www.codinghorror.com/blog/2008/ 10/the-problem-with-urls.html "By Jeff Atwood") i [Poprawiony, liberalny, dokładny wzór Regex dla pasujących adresów URL] (http://daringfireball.net/2010/07/improved_regex_for_matching_urls "John Gruber") i [URLwichfication (HTTP/FTP)] (http://jmrware.com/articles/2010/linkifyurl/linkify.html "Na twoje prawdziwie"). – ridgerunner

1

Zainspirowany odpowiedzią Akarun, wpadłem na tę funkcję, aby obsłużyć wszystkie protokoły i łącza sztuka tylko www.

function make_links($text, $class='', $target='_blank'){ 
    return preg_replace('!((http\:\/\/|ftp\:\/\/|https\:\/\/)|www\.)([-a-zA-Zа-яА-Я0-9\~\!\@\#\$\%\^\&\*\(\)_\-\=\+\\\/\?\.\:\;\'\,]*)?!ism', 
    '<a class="'.$class.'" href="//$3" target="'.$target.'">$1$3</a>', 
    $text); 
} 

funkcja ta opcjonalne parametry, aby dodać nazwy klas na linki, a także opcjonalny cel dla łącza, więc otworzyć się na nowe okna/zakładki ... domyślnie parametr otwiera linków do nowych window/tab, ale jeśli nie chcesz tego robić, możesz zmienić wartość domyślną lub zmienić wartość podczas wywoływania funkcji.

2

Również zainspirowany odpowiedzią Akarun, poniższa funkcja zwróci się do linków tylko tekst, który nie jest jeszcze linkiem. Dodana funkcjonalność jest sprawdzenie, czy związek z przechwyconego link tekstowy nie istnieje już w ciągu docelowym:

function make_links_from_http($content) { 
    // Links out of text links 
    preg_match_all('!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()[email protected]:%_+.~#?&;//=]+)!i', $content, $matches); 
    foreach ($matches[0] as $key=>$link) { 
     if (!preg_match('!<a(.*)'.$link.'(.*)/a>!i', $content)) 
     { 
      $content = str_replace($link, '<a href="'.$link.'" target="_blank">'.$link.'</a>', $content); 
     } 
    } 

    return $content; 
} 

testując, zauważyłem, że powyższa funkcja nie działa na linii # 5. Funkcja "bałaganu", który spełnia swoje zadanie jest następujące:

function make_links_from_http($content) 
{ 
    // The link list 
    $links = array(); 

    // Links out of text links 
    preg_match_all('!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()[email protected]:%_+.~#?&;//=]+)!i', $content, $matches); 
    foreach ($matches[0] as $key=>$link) 
    { 
     $links[$link] = $link; 
    } 

    // Get existing 
    preg_match_all('/<a\s[^>]*href=([\"\']??)([^\" >]*?)\\1[^>]*>(.*)<\/a>/siU', $content, $matches); 
    foreach ($matches[2] as $key=>$value) 
    { 
     if (isset($links[$value])) 
     { 
      unset($links[$value]); 
     } 
    } 

    // Replace in content 
    foreach ($links as $key=>$link) 
    { 
     $content = str_replace($link, '<a href="'.$link.'" target="_blank">'.$link.'</a>', $content); 
    } 

    return $content; 
} 

Dla nowego kodu, użyłem tutorial pod adresem: http://www.the-art-of-web.com/php/parse-links/

2
function makeClickableLinks($text) 
{ 
$text = html_entity_decode($text); 
$text = " ".$text; 
$text= preg_replace("/(^|[\n ])([\w]*?)([\w]*?:\/\/[\w]+[^ \,\"\n\r\t<]*)/is", "$1$2<a href=\"$3\" >$3</a>", $text); 
$text= preg_replace("/(^|[\n ])([\w]*?)((www|wap)\.[^ \,\"\t\n\r<]*)/is", "$1$2<a href=\"http://$3\" >$3</a>", $text); 
$text= preg_replace("/(^|[\n ])([\w]*?)((ftp)\.[^ \,\"\t\n\r<]*)/is", "$1$2<a href=\"$4://$3\" >$3</a>", $text); 
$text= preg_replace("/(^|[\n ])([a-z0-9&\-_\.]+?)@([\w\-]+\.([\w\-\.]+)+)/i", "$1<a href=\"mailto:[email protected]$3\">[email protected]$3</a>", $text); 
$text= preg_replace("/(^|[\n ])(mailto:[a-z0-9&\-_\.]+?)@([\w\-]+\.([\w\-\.]+)+)/i", "$1<a href=\"[email protected]$3\">[email protected]$3</a>", $text); 
$text= preg_replace("/(^|[\n ])(skype:[^ \,\"\t\n\r<]*)/i", "$1<a href=\"$2\">$2</a>", $text); 
     return $text; 
} 

praca z:

www. example.com

https://www.example.com

http://www.example.com

wap.example.com

ftp.example.com

[email protected]

skype Przykład

mailto: użytkownik @ przykładzie.com

atherprotocol: //example.com

Powiązane problemy