Link being replaced not expected way when using preg_replace

62 Views Asked by At

I've a array with regular expressions I use to replace URL's/hashtags with links using preg_replace:

$regs = array('!(\s|^)((https?://|www\.)+[a-z0-9_./?=;&#-]+)!i', '/#(\w+)/');
$subs = array(' <a href="$2" target="_blank">$2</a>', '<a href="/hashtag/$1" title="#$1">#$1</a>');

$output = preg_replace($regs, $subs, $content);

If $content have a link, for ex: https://www.google.com/, it replaces correctly; if have a hashtag followed a text, for ex: #hello replace too, however, if have a link with a hashtag, for ex: https://www.google.com/#top the replacement is as follows:

#top" target="_blank">https://www.google.com/#top
^^^^                                         ^^^^

and only the highlighted parts turn into links.

How to fix?

1

There are 1 best solutions below

1
On BEST ANSWER

It is because your second regex in array is also matching part after # in string.

Change your regex to:

$regs = array('!(\s|^)((https?://|www\.)+[a-z0-9_./?=;&#-]+)!i', '/(?<=[\'"\s]|^)#(\w+)/');
$subs = array(' <a href="$2" target="_blank">$2</a>', '<a href="/hashtag/$1" title="#$1">#$1</a>');
$content = 'https://www.google.com/#top foobar #name';

# now use in preg_replace
echo preg_replace($regs, $subs, $content);

It will give you:

<a href="https://www.google.com/#top" target="_blank">https://www.google.com/#top</a> foobar <a href="/hashtag/name" title="#name">#name</a>