0

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?

Mohammad Saberi
  • 12,864
  • 27
  • 75
  • 127

3 Answers3

15
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

splash58
  • 26,043
  • 3
  • 22
  • 34
  • 1
    This works - better than others found via the googles. And I note that it also works with URIs that contain those pesky umlauts . Huzzah !! – Rick Hellewell Jan 09 '17 at 19:13
  • Thanks for sharing this! What are the `@` symbols in the beginning and end of the pattern? Instead if `/REGEX_PATTERN/` slashes? – Mohammed AlBanna Jul 12 '19 at 22:49
  • 1
    @MohammadAlBanna Yes, you can use some char as delimiter, not only slash - https://www.php.net/manual/en/regexp.reference.delimiters.php – splash58 Jul 13 '19 at 09:42
  • 1
    I don't know why this answer was accepted, but this will also convert any word followed by a dot followed by something else into an anchor. For example: Vestibulum pretium nibh eu sollicitudin tincidunt. this will convert " tincidunt" into an anchor – user765368 Feb 03 '20 at 17:46
  • Not to mention that this answer is missing its educational explanation. – mickmackusa Jan 29 '23 at 20:49
5
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!

Gero Nikolov
  • 93
  • 1
  • 8
1
$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.

wp-mario.ru
  • 798
  • 7
  • 12