Question

I have a php function that changes urls to links. But I have problem when I insert for example pictures in format <img src="http://somelink.com/picture.jpg"> it also changes the inside url to link. How should I prevent this?

<?php
$string='http://www.somelink.com';
echo makelink($string);

function makeLink($string){

$string = preg_replace("/([^\w\/])(www\.[a-z0-9\-]+\.[a-z0-9\-]+)/i","$1http:$2",$string);
$string = preg_replace("/([\w]+:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/i","<a target=\"_blank\" href=\"$1\">$1</A>",$string);
$string = preg_replace("/([\w-?&;#~=\.\/]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?))/i","<A HREF=\"mailto:$1\">$1</A>",$string);

return $string;
}

?>

So, for exaple when I have input like this:

<img src="http://somelink.com/img.jpg"> http://somelink.com

I need the output to look like this:

<img src="http://somelink.com/img.jpg"> <a href="http://somelink.com" target="_blank">http://somelink.com</a>

What my code do now is:

<img src="<a href="http://somelink.com/img.jpg" target="_blank">http://somelink.com/img.jpg</a>"> <a href="http://somelink.com" target="_blank">http://somelink.com</a>

I hope you see the problem

Was it helpful?

Solution

You can use a negative lookbehind in REGEX to check if something DOES NOT precede what you want to match.

Say that you had this expression for matching URLs:

((?:http(?:s)?://)(?:www\.)?[-A-Z0-9.]+(?:\.com)[-A-Z0-9_./]?(?:[-A-Z0-9#?/]+)?)

This expression would match the following types of URLs:

http://www.example.com
http://example.com/
https://www.example.com/seconday/somepage#hashes?parameters
https://www.example.com/seconday/
http://www.example.com/seconday
http://example.com/seconday
http://example.com/seconday/

So then you could just add a negative lookbehind to the front of it to check for a quote, tick or equal sign. If it finds one of those, then it won't make a match.

Here is what the negative lookbehind would look like:

(?<!(?:"|'|=))

And you can just put that in front of the other REGEX. Here is what this means:

(?<!   (?:   "|'|=   )   )
 1      2      3     4   5
  1. (?<! Negative Lookbehind - This says make sure that whatever is coming up next cannot be present in front of the string.
  2. (?: Non-Capturing Parenthesis - We are going to be putting a group consisting of a quote ", tick ' or equal sign =, but we don't want to capture it. We just want to check for any one of those. By default, REGEX remembers anything inside of a parenthesis (, so we add the ?: to tell it not to.
  3. "|'|= Look for either a quote ", a tick ' or an equal sign =.
  4. ) Closing parenthesis for the "or" grouping of "|'|=
  5. ) Closing parenthesis for the negative lookbehind.

Okay, putting it all together, the REGEX would look like this:

(?<!(?:"|'|=))((?:http(?:s)?://)(?:www\.)?[-A-Z0-9.]+(?:\.com)[-A-Z0-9_./]?(?:[-A-Z0-9#?/]+)?)

Here is a link to a demo of the REGEX

Here is a link to a demo of the REGEX in a PHP script

Really, the only thing I had to do to the REGEX to get this to work in PHP was to escape the tick, since I was using ticks to enclose my expression.

OTHER TIPS

You may want to try this:

<?php
    $html = '<img src="http://somelink.com/img.jpg"> http://somelink.com';
    $link = preg_replace('%<img src="(.*)/(.*?)">\s*(.*?)\s*$%m', '<img src="$1/$2"> <a href="$1" target="_blank">$3</a>', $html );
    echo $link;
`   //<img src="http://somelink.com/img.jpg"> <a href="http://somelink.com" target="_blank">http://somelink.com</a>
?>

DEMO
https://ideone.com/fgGaYK

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top