0

I am trying to match ALL hyperlinks, i.e:

So far this piece of code, does the job pretty good:

        /**
         * Convert links
         */

            $str = preg_replace('$(https?://[a-z0-9_./?=&#-]+)(?![^<>]*>)$i', ' <a href="$1" target="_blank">$1</a> ', $str." ");
            $str = preg_replace('$(www\.[a-z0-9_./?=&#-]+)(?![^<>]*>)$i', '<a href="http://$1"  target="_blank">$1</a> ', $str." ");

But I have stumbled upon two VALID links that does not work. See:

Any solution that would find ALL matching links?

FooBar
  • 5,752
  • 10
  • 44
  • 93
  • So `troll.lol` is also valid? On that note, [check this question](http://stackoverflow.com/questions/37684/how-to-replace-plain-urls-with-links) – HamZa May 05 '14 at 10:17

2 Answers2

0

Only adding few chars inside your character class and making it case insensitive takes it all the way. But not pretty to look at :)

(?i)(https?://[a-z0-9_./?=&#-,;-]+)(?![^<>]*>)
Hans Schindler
  • 1,787
  • 4
  • 16
  • 25
0

I ended up using this:

/**
 * Convert URL to links
 */

    function make_links($text) {
      return  preg_replace(
         array(
           '/(?(?=<a[^>]*>.+<\/a>)
                 (?:<a[^>]*>.+<\/a>)
                 |
                 ([^="\']?)((?:https?|ftp|bf2|):\/\/[^<> \n\r]+)
             )/iex',
           '/<a([^>]*)target="?[^"\']+"?/i',
           '/<a([^>]+)>/i',
           '/(^|\s)(www.[^<> \n\r]+)/iex',
           '/(([_A-Za-z0-9-]+)(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-]+)
           (\\.[A-Za-z0-9-]+)*)/iex'
           ),
         array(
           "stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\">\\2</a>\\3':'\\0'))",
           '<a\\1',
           '<a\\1 target="_blank">',
           "stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\">\\2</a>\\3':'\\0'))",
           "stripslashes((strlen('\\2')>0?'<a href=\"mailto:\\0\">\\0</a>':'\\0'))"
           ),
           $text
       );
    }

Seems to be working pretty good so far.

FooBar
  • 5,752
  • 10
  • 44
  • 93