How to add anchor tag to a URL from text input
Here is my code to format all the links inside text including emails, urls with and without protocol.
public function formatLinksInText($text)
{
//Catch all links with protocol
$reg = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(\/\S*)?/';
$formatText = preg_replace($reg, '<a href="$0" style="font-weight: normal;" target="_blank" title="$0">$0</a>', $text);
//Catch all links without protocol
$reg2 = '/(?<=\s|\A)([0-9a-zA-Z\-\.]+\.[a-zA-Z0-9\/]{2,})(?=\s|$|\,|\.)/';
$formatText = preg_replace($reg2, '<a href="//$0" style="font-weight: normal;" target="_blank" title="$0">$0</a>', $formatText);
//Catch all emails
$emailRegex = '/(\S+\@\S+\.\S+)\b/';
$formatText = preg_replace($emailRegex, '<a href="mailto:$1" style="font-weight: normal;" target="_blank" title="$1">$1</a>', $formatText);
$formatText = nl2br($formatText);
return $formatText;
}
I adapted Jonathan Sampson's regex option so that it is more lenient about what is a domain (doesn't need http(s) to qualify).
function hyperlinksAnchored($text) {
return preg_replace('@(http)?(s)?(://)?(([-\w]+\.)+([^\s]+)+[^,.\s])@', '<a href="http$2://$4">$1$2$3$4</a>', $text);
}
Works for these URLs (and successfully leaves out trailing period or comma):
http://www.google.com/
https://www.google.com/.
www.google.com
www.google.com.
www.google.com/test
google.com
google.com,
google.com/test
123.com/test
www.123.com.au
ex-ample.com
http://ex-ample.com
http://ex-ample.com/test-url_chars.php?param1=val1.
http://ex-ample.com/test-url_chars?param1=value1¶m2=val+with%20spaces
Hope that helps someone.
Refining Markd's answer to avoid links on decimals, percentages, numerical dates (10.3.2001), ellipsis and IP addresses:
function addLinks($text) {
return preg_replace('@(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@', '<a target="ref" href="http$2://$4">$1$2$3$4</a>', $text);
}
Works for:
http://www.google.com/
https://www.google.com/.
www.google.com
www.google.com.
www.google.com/test
google.com
google.com,
google.com/test
www.123.com.au
ex-ample.com
http://ex-ample.com
http://ex-ample.com/test-url_chars.php?param1=val1.
http://ex-ample.com/test-url_chars?param1=value1¶m2=val+with%20spaces
Does not work for:
123.com/test (numeric domains without 'www')
Keep it up press of popular opinion........keep the average (ellipsis)
Rising 3.8% to 3.94 million from 3.79 million (percentages and decimals)
Edited by Andrew Brooke - 07.08.2013 19:57 (dd.mm.yyyy dates)
10.1.1.1 (IP Addresses)
First, a request. Don't do this before writing the data to the database. Instead, do it before displaying the data to the end-user. This will cut down on all confusion, and will allow you more flexibility in the future.
One example found online follows:
$text = preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)?)@', '<a href="$1">$1</a>', $text);
And a much more thorough one from daringfireball.net:
/**
* Replace links in text with html links
*
* @param string $text
* @return string
*/
function auto_link_text($text)
{
$pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\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) . "…";
}
return sprintf(\'<a rel="nowfollow" href="%s">%s</a>\', $url, $text);
');
return preg_replace_callback($pattern, $callback, $text);
}