1

I am trying to replace image links, youtube video links and regular links separately with appropriate html tags and im having trouble targeting just the regular links: Here's my code:

 function($text)
  {
    $output = preg_replace('#(http://([^\s]*)\.(jpg|gif|png))#', 
                        '<br/><img src="$1" alt="" width="300px" style = "clear:both;"/><br/>', $text);

        $output = preg_replace('#(http://([^\s]*)youtube\.com/watch\?v=([^\s]*))#', 
                      '<br/><iframe width="480px" height="385px" src="http://www.youtube.com/embed/$3"
                       frameborder="0" allowfullscreen style = "clear:both;"></iframe><br/>', $output);

    $output = preg_replace('#(http://([^\s]*)\.(com))#', 
                      '<br/><a href="$1">$1</a><br/>', $output);

    return $output

 }

This is instead replacing all links in the last step...how do i avoid this and replace only links (that arent youtubes or images) in the last step?

Thanks!

algorithmicCoder
  • 6,595
  • 20
  • 68
  • 117

2 Answers2

1

The urls your looking for need to be delimited by something such as spaces or new lines. Just add your delimiter to the regexes, so the the last regex is not too greedy! eg...

<?php

$text = "
http://www.youtube.com/watch?v=yQ4TPIfCK9A&feature=autoplay&list=FLBIwq18tUFrujiPd3HLPaGw&playnext=1\n
http://www.asdf.com/asdf.png\n
http://www.asdf.com\n
";

var_export($text);
var_export(replace($text));

function replace($text)
{
    $output = preg_replace('#(http://([^\s]*)\.(jpg|gif|png))\n#', 
                        '<br/><img src="$1" alt="" width="300px" style = "clear:both;"/><br/>', $text);


    $output = preg_replace('#(http://([^\s]*)youtube\.com/watch\?v=([^\s]*))\n#', 
                      '<br/><iframe width="480px" height="385px" src="http://www.youtube.com/embed/$3"
                       frameborder="0" allowfullscreen style = "clear:both;"></iframe><br/>', $output);

    $output = preg_replace('#(http://([^\s]*)\.(com))\n#', 
                      '<br/><a href="$1">$1</a><br/>', $output);

    return $output;
}
  • you shouldnt need to modify it, providing $text gives urls that separated in some manner then you just use that separator to distinguish between a url that ends in .com and one that ends in .com/asdf.png – user1660098 Sep 17 '12 at 06:26
0

You could use preg_replace_callback to match each link just once. So you don't have to worry about modifying a link twice:

$input = <<<EOM
http://www.example.com/fritzli.jpeg

https://www.youtube.com/watch?v=blabla+bla+"+bla

http://wwww.google.com/search?q=blabla
EOM;
echo replace($input);

function replace($text) {
    $output = preg_replace_callback("#(https?://[^\s]+)#", function($umatch) {
        $url = htmlspecialchars($umatch[1]);

        if(preg_match("#\.(jpg|jpeg|gif|png|bmp)$#i", $url)) {
            $result = "<br/><img src=\"$url\" alt=\"\" width=\"300px\" "
                . " style = \"clear:both;\"/><br/>";
        } elseif(preg_match("#youtube\.com/watch\?v=([^\s]+)#", $url, $match)) {
            $result = "<br/><iframe width=\"480px\" height=\"385px\""
                . " src=\"http://www.youtube.com/embed/{$match[1]}\""
                . " frameborder=\"0\" allowfullscreen style = \"clear:both;\">"
                . "</iframe><br/>";
        } else {
            $result = "<br/><a href=\"$url\">$url</a><br/>";
        }

        return $result;
    }, $text);

    return $output;
}

Note: the code above works only with a PHP-version >= 5.3. If you use 5.3 or below you can just extract the inner function to a separate function and supply the function name as an argument to preg_replace_callback:

function replace_callback($umatch) {
    $url = htmlspecialchars($umatch[1]);

    if(preg_match("#\.(jpg|jpeg|gif|png|bmp)$#i", $url)) {
        $result = "<br/><img src=\"$url\" alt=\"\" width=\"300px\" "
            . " style = \"clear:both;\"/><br/>";
    } elseif(preg_match("#youtube\.com/watch\?v=([^\s]+)#", $url, $match)) {
        $result = "<br/><iframe width=\"480px\" height=\"385px\""
            . " src=\"http://www.youtube.com/embed/{$match[1]}\""
            . " frameborder=\"0\" allowfullscreen style = \"clear:both;\">"
            . "</iframe><br/>";
    } else {
        $result = "<br/><a href=\"$url\">$url</a><br/>";
    }

    return $result;
}

function replace($text) {
    $output = preg_replace_callback("#(https?://[^\s]+)#",
        "replace_callback", // the name of the inner function goes here
        $text);

    return $output;
}
vstm
  • 12,407
  • 1
  • 51
  • 47
  • Thanks! I get this error: Parse error: syntax error, unexpected T_FUNCTION on the line where $output is assigned to preg_replace_callback . Does this work for you? – algorithmicCoder Sep 17 '12 at 06:05
  • ah i believe this function requires php 5.3 and im on 5.2.17 – algorithmicCoder Sep 17 '12 at 06:11
  • @algorithmicCoder: Hmm I guess you don't use PHP >= 5.3 then. You can resolve this by moving the inner function to a own function (like `function replace_inner($umatch) { ...}`) and passing "replace_inner" as second parameter to `preg_replace_callback`. Should I modify my example? – vstm Sep 17 '12 at 06:12
  • just seeing this. Yes please modify your example..would be very helpful! – algorithmicCoder Oct 06 '12 at 21:42
  • @algorithmicCoder: Thank you for the response, I have now extended my post. – vstm Oct 07 '12 at 09:03