1
votes

I wish to have a function that I could parse in text and then it will replaces all the links that contain of (jpg|png|gif|jpeg|bmp) extension with <img> tag, after that it will also replaces all the other links without (jpg|png|gif|jpeg|bmp) extension with <a> tag.

For example it should replaces:

http://imgur.com/gallery/TpGvHBL http://i.imgur.com/TpGvHBL.jpg

to

<a href="http://imgur.com/gallery/TpGvHBL" target="_blank">http://imgur.com/gallery/TpGvHBL</a> <img src="http://i.imgur.com/TpGvHBL.jpg" />

===========================================================================

Currently I'm able to replace image url to <img> tag using below regex:

$text = preg_replace('#((https?|ftp):\/\/([^\s]*)\.(jpg|gif|png))#', '<img src="$1" />', $text);

and also below to replace normal url to <a> tag:

$text = preg_replace('/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/i', '<a href="$1" target="_blank">$1</a>', $text);

What I want is to change the second regex to replace non image url only, as it will conflicted with my first regex.

Thank you.

3
What have you tried ? Stackoverflow isn't some free-service to get ready-bakked code. Try something and I'll be glad to help. Hints: 1) Try to match url's with those extensions 2) Save those url's in an array 3) loop through that array, remove those extensions 4) Loop through the array(without extensions) and try to do some regex replace, use \b to prevent false matches 5) enjoyHamZa
Hi @HamZa, actually I'm searching for a solution which can directly replace all the url in the text instead of using array, however, I had updated with the codes that I had tried, please give me some advice. Thanks!Ping

3 Answers

1
votes

Sorry for the late reply, I'm going to answer on the fly.

So here's the solution I came up with:

$string = 'some test http://imgur.com/gallery/TpGvHBL http://i.imgur.com/TpGvHBL.jpg something else ...';

$result = preg_replace_callback('~\b(?:https?|ftp|file)://\S+~i', function($v){
    if(preg_match('~\.jpe?g|\.png|\.gif|\.bmp$~i', $v[0])){ // if image
        return '<img src="' . $v[0] . '">';
    }else{
        return '<a href="' . $v[0] . '" target="_blank">' . $v[0] . '</a>';
    }
}, $string);

I thought of matching all url's and then check if there is an image extension. Of course the first regex is very loose and you might improve it ... Note that you need PHP 5.3+ since I'm using an anonymous function.

Regex explanation:

~                   # delimiter
    \b              # word boundary
    (?:             # start of a non-capturing group
        https?      # match http or https
        |           # or
        ftp         # match ftp (you may want to add sftp o_O ?)
        |           # or
        file        # match file
    )               # end of the non-capturing group
    ://             # match ://
    \S+             # match anything except whitespace one or more times
~                   # delimiter, end of expression
i                   # set the i modifier : match case-insensitive

The second regex ~\.jpe?g|\.png|\.gif|\.bmp$~i just matches the following extensions jpg, jpeg, png, gif and bmp at the end of the string.

0
votes

I hope this is what you are looking for

Solution 1:

<?php
$str="http://imgur.com/gallery/TpGvHBL http://i.imgur.com/TpGvHBL.jpg";
$new_str=explode(" ",$str);
$str="<a href=".$new_str[0]." target=_blank>".$new_str[0]."</a>";
$str.=" <img src=".$new_str[1]." />";
echo htmlentities($str);

OUTPUT:

<a href=http://imgur.com/gallery/TpGvHBL target=_blank>http://imgur.com/gallery/TpGvHBL</a> <img src=http://i.imgur.com/TpGvHBL.jpg />

Solution 2:

<?php
//$str='http://imgur.com/gallery/TpGvHBL';
$str='http://i.imgur.com/TpGvHBL.jpg';
if(is_array(getimagesize($str)))
{
echo "Image<br>";
    $str="<img src=".$str." />";
}
else
{
    echo "Link<br>";
    $str="<a href=".$str." target=_blank>".$str."</a>";
}
echo htmlentities($str);

OUTPUT:

Image
http://i.imgur.com/TpGvHBL.jpg
0
votes

@hamza's RegExp misses some symbols that cannot belong to URL, e.g. quotes, parentheses etc.

I would suggest to change this:

~\b(?:https?|ftp|file)://\S+~i

to this:

~\b(?:https?|ftp|file):\/\/[^\s"'(){}<>|\\^~`]+~i