Turn Plain Text Urls into Active Links Using PHP

Turn Plain Text URLs into Active Links using PHP

You may wonder how it works. I'll try to explain how it should be done by various methods. We'll start first with how regex works and how it is used.


Regex - Regular expression

In computing, a regular expression (abbreviated regex or regexp) is a
sequence of characters that forms a search pattern, mainly for use in
pattern matching with strings, or string matching, i.e. "find and
replace"-like operations.

Basic Syntax

To use regular expressions first you need to learn the syntax. This syntax consists of a series of letters, numbers, dots, hyphens and special signs, which we can group together using different parentheses.

^               The circumflex symbol matches the beginning of the input string or line, although in some cases it can be omitted
$ Same as with the circumflex symbol, the dollar sign matches the end of the input string or line
. The period matches any single character
? It will match the preceding pattern zero or one times
+ It will match the preceding pattern one or more times
* It will match the preceding pattern zero or more times
| Boolean OR
- Used when describing a range of elements
() Groups pattern elements together
[] Matches any single character between the square brackets
{min, max} Used to match exact character counts, where min and max are integers
\d Matches any single digit
\D Matches any single non digit caharcter
\w Matches any alpha numeric character including underscore (_)
\W Matches any non alpha numeric character excluding the underscore character
\s Matches any single whitespace character

Brackets

Brackets [] have a special meaning when used in the context of regular expressions. They are used to find a range of characters.

[0-9]           Matches any decimal digit from 0 through 9.
[a-z] Matches any character from lowercase a through lowercase z.
[A-Z] Matches any character from uppercase A through uppercase Z.
[a-Z] Matches any character from lowercase a through uppercase Z.

Examples

Let's look at how to use properly the operators. We will do this with an example of the word hello.

/hello/       Matches the word hello
/^hello/ Matches hello at the start of a string. Possible matches are hello or helloworld, but not worldhello
/hello$/ Matches hello at the end of a string or line.
/he.o/ Matches any character between he and o. Possible matches are helo or heyo, but not hello
/he?llo/ Matches either hllo or hello
/hello+/ Matches hello one or more times. E.g. matches hello or hellohello
/he*llo/ Matches llo, hello or hehello, but not hellooo
/hello|world/ Matches either hello or world
/(A-Z)/ Using the hyphen character to denote a range, matches every uppercase character from A to Z. E.g. A, B, C…
/[abc]/ Matches any single character a, b or c
/abc{1}/ Matches precisely one c character after the characters ab. E.g. matches abc, but not abcc
/abc{1,}/ Matches one or more c character after the characters ab. E.g. matches abc or abcc
/abc{2,4}/ Matches between two and four c character after the characters ab. E.g. matches abcc, abccc or abcccc, but not abc

The most common

[^a-zA-Z]       Matches any string not containing any of the characters ranging from a through z and A through Z.
p.p Matches any string containing p, followed by any character, in turn followed by another p.
^.{2}$ Matches any string containing exactly two characters.
<b>(.*)</b> Matches any string enclosed within <b> and </b>.
p(hp)* Matches any string containing a p followed by zero or more instances of the sequence hp.

Regex to match a URL

At first let's look how a URL is built. We only have a couple of options:

  • http://example.com/
  • https://example.com/
  • ftp://example.com/
  • www.example.com
  • user@example.com
  • 127.0.0.1
  • http://example.com:8080/

http://, https://, ftp, www, mail, ip and port.

Method 1 (1/10 points)

// Only mails
$match = preg_match('/[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)*\@[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)+/', $string, $array);

Method 2 (5/10 points)

// Without ports, www-s, ip-s and mails
$text = ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]","<a href=\"\\0\">\\0</a>", $text);

Method 3 (10/10 points)

/* Proposed by:
* Søren Løvborg
* http://stackoverflow.com/users/136796/soren-lovborg
*/

$rexProtocol = '(https?://)?';
$rexDomain = '((?:[-a-zA-Z0-9]{1,63}\.)+[-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})';
$rexPort = '(:[0-9]{1,5})?';
$rexPath = '(/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?';
$rexQuery = '(\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
$rexFragment = '(#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';

function callback($match)
{
// Prepend http:// if no protocol specified
$completeUrl = $match[1] ? $match[0] : "http://{$match[0]}";

return '<a href="' . $completeUrl . '">'
. $match[2] . $match[3] . $match[4] . '</a>';
}

$text = preg_replace_callback("&\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))&",
'callback', htmlspecialchars($text));

You can write your own ideas to my answer.


I am writing...

Convert plain text URLs into HTML hyperlinks in PHP

Here is another solution, This will catch all http/https/www and convert to clickable links.

$url = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i'; 
$string = preg_replace($url, '<a href="$0" target="_blank" title="$0">$0</a>', $string);
echo $string;

Alternatively for just catching http/https then use the code below.

$url = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/';   
$string= preg_replace($url, '<a href="$0" target="_blank" title="$0">$0</a>', $string);
echo $string;

EDIT:
The script below will catch all URL types and convert them to clickable links.

$url = '@(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
$string = preg_replace($url, '<a href="http$2://$4" target="_blank" title="$0">$0</a>', $string);
echo $string;

The new update, If you're having the string strip the (s) then use the below code block, Thanks to @AndrewEllis for pointing this out.

$url = '@(http(s)?)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
$string = preg_replace($url, '<a href="http$2://$4" target="_blank" title="$0">$0</a>', $string);
echo $string;

Here's a very simple solution for the URL not displaying correctly.

$email = '<a href="mailto:email@email.com">email@email.com</a>';
$string = $email;
echo $string;

It is a very simple fix but you will have to modify it for your own purpose.

I've provided multiple answers as some servers are set up differently, so one answer may work for some but not for others, but I hope the answer(s) work for you and if not then let me know, and hopefully, I can come up with another solution.

There are multiple scripts as some PHP files require different scripts also some servers are set up differently, Plus each has different requirements, Some want just HTTP/S, some want WWW and some want FTP/S, Each one will work depending on how the users own scripts are set up, I provided some text with each one with what they do.

convert plain text URLs to HTML hyperlinks in PHP

How about running them through a regular expression like the following used to re-activate Twitter links -

http://www.burnmind.com/howto/how-to-convert-twitter-mentions-and-urls-to-active-links-using-regular-expressions-in-php

Making an active link in PHP

You need to convert the part of the string which is a URL to a link.

// The Regular Expression filter
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";

// The Text you want to filter for urls
$text = "The text you want to filter goes here. http://google.com";

// Check if there is a url in the text
if(preg_match($reg_exUrl, $text, $url))
{
// make the urls hyper links
echo preg_replace($reg_exUrl, "<a href="{$url[0]}">{$url[0]}</a> ", $text);
} else {
// if no urls in the text just return the text
echo $text;
}

PHP / RegEx - Convert URLs to links by detecting .com/.net/.org/.edu etc

You can use this regex:

#(\s|^)((?:https?://)?\w+(?:\.\w+)+(?<=\.(net|org|edu|com))(?:/[^\s]*|))(?=\s|\b)#is

Code:

$arr = array(
'http://www.domain.com/?foo=bar',
'http://www.that"sallfolks.com',
'This is really cool site: https://www.domain.net/ isn\'t it?',
'http://subdomain.domain.org',
'www.domain.com/folder',
'Hello! You can visit vertigofx.com/mysite/rocks for some awesome pictures, or just go to vertigofx.com by itself',
'subdomain.domain.net',
'subdomain.domain.edu/folder/subfolder',
'Hello! Check out my site at domain.net!',
'welcome.to.computers',
'Hello.Come visit oursite.com!',
'foo.bar',
'domain.com/folder',

);
foreach($arr as $url) {
$link = preg_replace_callback('#(\s|^)((?:https?://)?\w+(?:\.\w+)+(?<=\.(net|org|edu|com))(?:/[^\s]*|))(?=\s|\b)#is',
create_function('$m', 'if (!preg_match("#^(https?://)#", $m[2]))
return $m[1]."<a href=\"http://".$m[2]."\">".$m[2]."</a>"; else return $m[1]."<a href=\"".$m[2]."\">".$m[2]."</a>";'),
$url);
echo $link . "\n";

OUTPUT:

<a href="http://www.domain.com/?foo=bar">http://www.domain.com/?foo=bar</a>
http://www.that"sallfolks.com
This is really cool site: <a href="https://www.domain.net">https://www.domain.net</a>/ isn't it?
<a href="http://subdomain.domain.org">http://subdomain.domain.org</a>
<a href="http://www.domain.com/folder">www.domain.com/folder</a>
Hello! You can visit <a href="http://vertigofx.com/mysite/rocks">vertigofx.com/mysite/rocks</a> for some awesome pictures, or just go to <a href="http://vertigofx.com">vertigofx.com</a> by itself
<a href="http://subdomain.domain.net">subdomain.domain.net</a>
<a href="http://subdomain.domain.edu/folder/subfolder">subdomain.domain.edu/folder/subfolder</a>
Hello! Check out my site at <a href="http://domain.net">domain.net</a>!
welcome.to.computers
Hello.Come visit <a href="http://oursite.com">oursite.com</a>!
foo.bar
<a href="http://domain.com/folder">domain.com/folder</a>

PS: This regex only supports http and https scheme in URL. So eg: if you want to support ftp also then you need to modify the regex a little.

Best way to make links clickable in block of text

Use this (works with ftp, http, ftps and https schemes):

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

How to make a link grabbed from a database display as a clickable active link?

You propably want your script to automatically detect links...I did that a few weeks ago on a script that pulls tweets from an RSS Feed...this is the code. You can replace $_POST['inputfield'] with the appropriate variable!

if (preg_match('/www./',$_POST['inputfield'])) //checks if there's www. in the field. alternatively use http: instead of www.
{
$link_start_pos = strpos($_POST['inputfield'],'www.'); //returns the link-start-pos, alternatively use http: instead of www.

// find the end of the link
if($link_end_pos = strpos($_POST['inputfield'], ' ', $link_start_pos) === false)
{ //if theres no space after the link, it's propably on the end of the text
$link_end_pos = strlen($_POST['inputfield']);
}
// form a string with the actual link in it
$link = substr($_POST['inputfield'],$link_start_pos,$link_end_pos);
// and make it clickable
$link_insert = '<a href="'.$link.'" target="_blank">'.$link.'</a>';
}

Hope that helps



Related Topics



Leave a reply



Submit