Karem
Karem

Reputation: 18103

Auto-link URLs in a string

I have a normal message output $msg. I want it to make it links, if it is links. (containing http:// or www.) then it should make it <a href="http://google.com" target="_blank">http://google.com</a>

I have stripped html from the messages

$msg = htmlspecialchars(strip_tags($show["status"]), ENT_QUOTES, 'utf-8')

How can that be done, seen it many places.

Upvotes: 1

Views: 10003

Answers (4)

walterra
walterra

Reputation: 862

I had the same problem like @SublymeRick (stops after first dot, see Auto-link URLs in a string).

With a little inspiration from https://stackoverflow.com/a/8218223/593957 I changed it to

$msg = preg_replace('/((http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?)/', '<a href="\1">\1</a>', $msg);

Upvotes: 7

user7487108
user7487108

Reputation: 1

enter code h    function AutoLinkUrls($str,$popup = FALSE){
    if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches)){
        $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
        for ($i = 0; $i < count($matches['0']); $i++){
            $period = '';
            if (preg_match("|\.$|", $matches['6'][$i])){
                $period = '.';
                $matches['6'][$i] = substr($matches['6'][$i], 0, -1);
            }
            $str = str_replace($matches['0'][$i],
                    $matches['1'][$i].'<a href="http'.
                    $matches['4'][$i].'://'.
                    $matches['5'][$i].
                    $matches['6'][$i].'"'.$pop.'>http'.
                    $matches['4'][$i].'://'.
                    $matches['5'][$i].
                    $matches['6'][$i].'</a>'.
                    $period, $str);
        }//end for
    }//end if
    return $str;
}//end AutoLinkUrlsere

Upvotes: 0

Spudley
Spudley

Reputation: 168685

Use a regular expression for this, via PHP's preg_replace() function.

Something like this....

preg_replace('/\b(https?:\/\/(.+?))\b/', '<a href="\1">\1</a>', $text);

Explaination:

Looks for (https?://(.+?)) surrounded by \b, which is a beginning-of-word / end-of-word marker.

https?:// is obvious (the s? means that the 's' is optional).

(.+?) means any number of any characters: 'any character' is represented by the dot; 'any number of' is the plus sign. The question mark means it isn't greedy, so it will allow the item after it (ie the \b end of word) to match at the first opportunity. This stops it just carrying on till the end of the string.

The whole expression is in brackets so that it gets picked up the the replacement system and can be re-inserted using \1 in the second parameter.

Upvotes: 2

symcbean
symcbean

Reputation: 48357

Something like:

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

maybe?

Upvotes: 0

Related Questions