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/>$1<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!
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/>$1<br/>', $output);
return $output;
}
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/>$url<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/>$url<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;
}
Related
I need to convert an img like this:
<img src="https://techcrunch.com/wp-content/uploads/2015/04/codecode.jpg" style="height:404px; width:602px" />
to this:
<amp-img src="https://techcrunch.com/wp-content/uploads/2015/04/codecode.jpg" height="404" width="602"></amp-img>
Keeping in mind that this code will be in a portion of code with more html tags and, important, I can't use any library or anything..
I await answers, thanks in advance!
You can Achieve your goal with following code :
function html5toampImage($string) {
preg_match('/src="(.+?)"/', $string, $src);
$srcAttribute = $src[0];
preg_match('/style="(.+?)"/', $string, $styles);
$style = $styles[1];
$allData = explode(";",$style);
foreach($allData as $data) {
if($data) {
list($key,$value) = explode(":",$data);
if(trim($key)=="height") {
$heightAttribute = trim($key).'="'.trim(str_replace("px","",$value)).'"';
}
if(trim($key)=="width") {
$widthAttribute = trim($key).'="'.trim(str_replace("px","",$value)).'"';
}
}
}
$ampImageTag = '<amp-img '.$srcAttribute.' '.$heightAttribute.' '.$widthAttribute.' layout="responsive"></amp-img>';
return $ampImageTag;
}
$html5Tag = '<img alt="aa" src="https://techcrunch.com/wp-content/uploads/2015/04/codecode.jpg" style="height:404px; width:602px; color:red" />';
echo htmlentities(html5toampImage($html5Tag));
Here is working eval url
I currently have a code that finds and replaces urls into complete html links. It works fine but now i need to update it so that if there is image url then it should convert it into a html img tag and display it. Function im using now is...
function auto_link_text($text) {
$pattern = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
$callback = create_function('$matches', '
$url = array_shift($matches);
$url_parts = parse_url($url);
return sprintf(\'<a rel="nowfollow" target="_blank" href="%s">%s</a>\', $url, $url);
');
return preg_replace_callback($pattern, $callback, $text);
}
Got it from...
How to add anchor tag to a URL from text input
Here is an example of the text i would to it to go through...
asdf
http://google.com/
asfd
http://yahoo.com/logo.jpg
http://www.apple.com/sdfsd.php?page_id=13&id=18210&status=active#1
http://youtube.com/logo.png
like it updated function to output...
asdf
<a rel="nowfollow" target="_blank" href="http://google.com/">http://google.com/</a>
asfd
<img src="http://yahoo.com/logo.jpg" class="example">
<a rel="nowfollow" target="_blank" href="http://www.apple.com/sdfsd.php?page_id=13&id=18210&status=active#1">http://www.apple.com/sdfsd.php?page_id=13&id=18210&status=active#1</a>
<img src="http://youtube.com/logo.png" class="example">
Big thanks in advance!
You can use this for example:
function create_anchor_tag($url, $text = false) {
if ($text===false) $text = $url;
return '<a rel="no-follow" target="_blank" href="' . $url . '">'
. $text . '</a>';
}
function create_image_tag($url) {
return '<img src="' . $url . '"/>';
}
function auto_link_text($text) {
$pattern = '~\b(?:(?:ht|f)tps?://|www\.)\S+(?<=[\PP?])~i';
$callback = function ($m) {
$img_ext = array('jpg', 'jpeg', 'gif', 'png');
$path = parse_url($m[0], PHP_URL_PATH);
$ext = substr(strrchr($path, '.'), 1);
if (in_array(strtolower($ext), $img_ext))
return create_image_tag($m[0]);
return create_anchor_tag($m[0]);
};
return preg_replace_callback($pattern, $callback, $text);
}
I used several functions to make it more clea[rn], but you can easily adapt it as you like.
Here is the nice post about the best suitable regex pattern for valid URL. I picked one from there to group all the URLs.
Online demo
Steps to follow:
simply extract the url.
put a check on the url and based on your own logic substitute the tag as shown in demo.
sample code: (get all the valid urls in groups. get it from index 1)
$re = "/(([A-Za-z]{3,9}:(?:\\/\\/)?(?:[-;:&=\\+\\$,\\w]+#)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\\+\\$,\\w]+#)[A-Za-z0-9.-]+)((?:\\/[\\+~%\\/.\\w-_]*)?\\??(?:[-\\+=&;%#.\\w_]*)#?(?:[\\w]*))?)/";
$str = "...";
preg_match_all($re, $str, $matches);
sample code: (substitute anchor tag (or what ever you want to add))
$re = "/(([A-Za-z]{3,9}:(?:\\/\\/)?(?:[-;:&=\\+\\$,\\w]+#)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\\+\\$,\\w]+#)[A-Za-z0-9.-]+)((?:\\/[\\+~%\\/.\\w-_]*)?\\??(?:[-\\+=&;%#.\\w_]*)#?(?:[\\w]*))?)/";
$str = "...";
$subst = '$1';
$result = preg_replace($re, $subst, $str);
I try to replace all images in a html document with inline image (data:image).
I've a sample code which does not work:
function data_uri($filename) {
$mime = mime_content_type($filename);
$data = base64_encode(file_get_contents($filename));
return "data:$mime;base64,$data";
}
function img_handler($matches) {
$image_element = $matches[1];
$pattern = '/(src=["\'])([^"\']+)(["\'])/';
$image_element = preg_replace($pattern, create_function(
$matches,
$matches[1] . data_uri($matches[2]) . $matches[3]),
$image_element);
return $image_element;
}
$content = (many) different img tags
$search = '(<img\s+[^>]+>)';
$content = preg_replace_callback($search, 'img_handler', $content);
Could somebody check this code? Thanks!
UPDATE:
(...) Warning file_get_contents() [function.file-get-contents]: Filename cannot be empty (...)
That means the src url is not in the handler :(
UPDATE 2
<?php
function data_uri($filename) {
$mime = mime_content_type($filename);
$data = base64_encode(file_get_contents($filename));
return "data:$mime;base64,$data";
}
function img_handler($matches) {
$image_element = $matches[0];
$pattern = '/(src=["\'])([^"\']+)(["\'])/';
$image_element = preg_replace_callback($pattern, create_function(
$matchess,
$matchess[1] . data_uri($matchess[2]) . $matchess[3]),
$image_element);
return $image_element;
}
$content = '<img class="alignnone" src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Googlelogoi.png/180px-Googlelogoi.png" alt="google" width="580" height="326" title="google" />';
$search = '(<img\s+[^>]+>)';
$content = preg_replace_callback($search, 'img_handler', $content);
echo $content;
?>
I've upload this test file -> http://goo.gl/vWl9B
Your regex is alright. You are using create_function() wrong. And subsequently the inner preg_replace_callback() doesn't work. The call to data_uri() happens before any regex-replacement takes place, hencewhy the undefined filename error.
Use a proper callback function:
$image_element = preg_replace_callback($pattern, "data_uri_callback", $image_element);
Then move your code into there:
function data_uri_callback($matchess) {
return $matchess[1] . data_uri($matchess[2]) . $matchess[3];
}
My problem is that retrieveName() is not getting $1's value, but $1 is working just fine in the previous instance.
function bbcode ($string)
{
// All the default bbcode arrays.
$bbcode = array(
'#\[quote=(.*?)\](.*?)\[/quote\]#si' =>
'<span class="bbcode_quote"><b>
<a href="userprofile.php?id='.stripslashes('$1').'" target="_blank">
<span class="fake_link">'.retrieveName('$1').'</span></a> Said:</b><BR/>$2</span><BR/>'
);
$output = preg_replace(array_keys($bbcode), array_values($bbcode), $string);
$output = str_replace("\\r\\n", "<br>", $output);
return $output;
}
EDIT:
there's no strip slashes, I wish it was that simple
function retrieveName($poster_id){
$get_name = mysql_query("SELECT * FROM users WHERE userid = 'sanitizeIn($poster_id)'")
or die(mysql_error());
$name_row = mysql_fetch_array($get_name);
return $name_row['username'];
}
function sanitizeIn ($string) {
$output = mysql_real_escape_string($string);
return $output;
}
Assuming you are using preg_* functions, as you should be, you should use $1 instead of \\1. Both are valid, but $1 is the preferred syntax.
Also, you might be more interested in one of the following:
$output = preg_replace("#\[quote=(.*?)\](.*?)\[/quote\]#sie",
"'<span class=\"bbcode_quote\"><b><a href=\"userprofile.php?id='.stripslashes('$1').'\"
target=\"_blank\"><span class=\"fake_link\">'.
retrieveName(stripslashes('$1')) . '</span></a> Said:</b><BR/>$2
</span><BR/>'",$input);
Or:
$output = preg_replace_callback("#\[quote=(.*?)\](.*?)\[/quote\]#si",function($m) {
return '<span class="bbcode_quote"><b><a href="userprofile.php?id=\\1"
target="_blank"><span class="fake_link">' .
retrieveName('\\1') . '</span></a> Said:</b><BR/>\\2
</span><BR/>';
},$input);
Try this way:
$output = preg_replace_callback("#\[quote=(.*?)\](.*?)\[/quote\]#si",function($matches) {
return '<span class="bbcode_quote"><b><a href="userprofile.php?id='.stripslashes($matches[1]).'" target="_blank"><span class="fake_link">' .
retrieveName($matches[1]).'</span></a> Said:</b><BR/>'.$matches[2].'</span><BR/>';
},$input);
i want to extract href link from text or string. i write a little function to do that but this is slow when a string to transform is large. My code is
function spy_linkIntoString_Format($text) {
global $inc_lang; $lang = $inc_lang['tlang_media'];
$it = explode(' ' ,$text);
$result = '';
foreach($it as $jt) {
$a = trim($jt);
if(preg_match('/((?:[\w\d]+\:\/\/)?(?:[\w\-\d]+\.)+[\w\-\d]+(?:\/[\w\-\d]+)*(?:\/|\.[\w\-\d]+)?(?:\?[\w\-\d]+\=[\w\-\d]+\&?)?(?:\#[\w\-\d]*)?)/', $jt)) {
$pros_lis = str_replace('www.','',$jt);
$pros_lis = (strpos($pros_lis, 'http://') === false ? 'http://'. $pros_lis : $pros_lis);
$urlregx = parse_url($pros_lis);
$host_name = (!empty($urlregx['host']) ? $urlregx['host'] : '.com');
if($host_name == 'youtube.com') {
$string_v = $urlregx['query']; parse_str($string_v, $outs); $stID = $outs['v'];
$result .= '<a title="Youtube video" coplay="'.$stID.'" cotype="1" class="media_spy_vr5" href="#"><span class="link_media"></span>'.$lang['vtype_youtube'].'</a> ';
} elseif($host_name == 'vimeo.com') {
$path_s = $urlregx['path']; $patplode = explode("/", $path_s); $stID = $patplode[1];
$result .= '<a title="Vimeo video" coplay="'.$stID.'" cotype="2" class="media_spy_vr5" href="#"><span class="link_media"></span>'.$lang['vtype_vimeo'].'</a> ';
} elseif($host_name == 'travspy.com') {
$result .= '</span>'.$pros_lis.' ';
} else {
$result .= '<span class="jkt_445 c8_big_corner"></span>'.$pros_lis.' ';
}
} else {
$result .= $jt.' ';
}
}
return trim($result);/**/
}
Can i do this run fast?
You should rewrite this to use preg_match_allinstead of splitting the text into words (i.e. drop the explode).
$regex = '/\b((?:[\w\d]+\:\/\/)?(?:[\w\-\d]+\.)+[\w\-\d]+(?:\/[\w\-\d]+)*(?:\/|\.[\w\-\d]+)?(?:\?[\w\-\d]+\=[\w\-\d]+\&?)?(?:\#[\w\-\d]*)?)\b/';
preg_match_all($regex, $text, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
$url = $match[0];
// your link generator
}
You seem to be breaking the text into words separated by spaces, and then matching each word against a regular expression. This is very time consuming indeed.
A faster way to do this is to perform the regular expression search on the entire text and then iterate over it's results.
preg_match_all($regex, $text, $result, PREG_PATTERN_ORDER);
foreach($result[0] as $jt){
//do what you normally do with $jt
}