0

I'm trying to replace url links (starting http:// ...) to html hyperlinks in a string with PHP, I use a regex for this, but the problem is there's conflicts with the html "&nbsp ;" characters.

So I used this, it seems to work with normal links, but if I add the rule (^&[^;]+?;) to avoid specials characters it doesn't work.

function shortlink($text) {
    return preg_replace_callback(
        '/(^|[^"])(((f|ht){1}tps?:\/\/)(^&[^;]+?;)[-a-zA-Z0-9@:;\[\]%_\+.~#!?&\/\/=]+)/i',
        'url_link',
        $text
    );
}

And this is the callback function:

function url_link($match) {
    return $match[1].'<a href="'.$match[2].'" target="_blank">'.(strlen($match[2])>50 ? substr($match[2], 0, 24).'<i>'.substr($match[2], 24, 1).'</i><span class="shortl">'.substr($match[2], 25, -19).'</span>'.substr($match[2], -19) : $match[2]).'</a>';
}

But this:

function shortlink($text) {
    return preg_replace_callback(
        '/(^|[^"])(((f|ht){1}tps?:\/\/)[-a-zA-Z0-9@:;\[\]%_\+.~#!?&\/\/=]+)/i',
        'url_link',
        $text
    );
}

Work fine, but the conflict still exists.

This example illustrates the problem. If I have a string

http://any_link&quote; 

this gives =>

<a href="http://any_link'">...

But I want :

<a href="http://any_link">

Any solution?

Elin
  • 6,507
  • 3
  • 25
  • 47
Saberdream
  • 187
  • 1
  • 9
  • Of course it doesn't work. The `^` in `(^&[^;]+?;)` means match begin of string. If you put it directly in the middle of your expression it would fail directly. Anyways, there's a lot of redundancy in your expression, for example `{1}` or escaping some characters in a character class etc... I think you want to take a look at `html_entity_decode()` or take a look at [this question](http://stackoverflow.com/q/406230). Btw, GTO is awesome. – HamZa Mar 05 '14 at 12:54
  • Refer to your link, I have to add a capture at the end of regex `'/(^|[^"])(((f|ht){1}tps?:\/\/)[-a-zA-Z0-9@:;\[\]%_\+.~#!?&\/\/=]+)(?:(?!&[^;]+?;).)/i',` but it totally change my regex btw. A way to add a non-capturing rule? – Saberdream Mar 05 '14 at 13:12

1 Answers1

0

Take a look at:

(f|ht){1}tps

This will only work with secured connections (httpS, ftpS). It won't match http or ftp.

ex3v
  • 3,518
  • 4
  • 33
  • 55
  • You need to take a look one character further `(f|ht){1}tps?`. The question mark makes the `s` optional. – HamZa Mar 05 '14 at 12:57