Mohammad Saberi
Mohammad Saberi

Reputation: 13166

Replace all URLs in text to clickable links in PHP

I have a web application written with PHP. I wanted to find all URLs inside users comments and change them to clickable links. I searched many websites and pages and found the solution below (Unfortunately I did not find its reference link again):

<?php
function convert($input) {
   $pattern = '@(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
   return $output = preg_replace($pattern, '<a href="http$2://$4">$0</a>', $input);
}
?>

This code works perfectly thanks to its author. But I found out there is a bug in it that I could not solve.
If detected URL started with s letter (without https), the href value won't have that s character and http will change to https, whereas inner text is correct.

Example:
source.com >> <a href="https://ource.com">source.com</a>

Do you have any solution to solve this bug?

Upvotes: 0

Views: 9413

Answers (3)

wp-mario.ru
wp-mario.ru

Reputation: 914

$pattern = '@(http(s)?://)?(([a-zA-Z0-9])([-\w]+\.)+([^\s\.<]+[^\s<]*)+[^,.\s<])@';

This is an update of the @splash58 answer and @Gero Nikolov answer. If the text ends with the < character, an error occurs.

Example:

<p>some text https://example.com</p>

Result:

<p>some text <a href="https://example.com</p>">https://example.com</p></a>

With the specified pattern, the result will be correct.

Upvotes: 1

Gero Nikolov
Gero Nikolov

Reputation: 93

function convert($input) {
   $pattern = '@(http(s)?://)?(([a-zA-Z0-9])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
   return $output = preg_replace($pattern, '<a href="http$2://$3">$0</a>', $input);
}

This is an update of the @splash58 dude answer to handle the URL which starts with number instead of letter. Example is 11hub.net or 9gag.com

Thank you splash58 for the great answer!

Upvotes: 5

splash58
splash58

Reputation: 26153

function convert($input) {
   $pattern = '@(http(s)?://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
   return $output = preg_replace($pattern, '<a href="http$2://$3">$0</a>', $input);
}

demo

Upvotes: 15

Related Questions