Reputation: 6799
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!
Upvotes: 1
Views: 134
Reputation: 12537
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;
}
Upvotes: 0
Reputation: 56
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;
}
Upvotes: 1