regex - PHP str_replace duplicates -
i have function convert user input various services youtube , opengraph
function link_to_opengraph($content) { // patterns author https://github.com/leonardocardoso/facebook-link-preview/blob/master/php/classes/regex.php // overall code inspiration https://github.com/leonardocardoso/facebook-link-preview/ $urlregex = "/(https?\:\/\/|\s)[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})(\/+[a-z0-9_.\:\;-]*)*(\?[\&\%\|\+a-z0-9_=,\.\:\;-]*)?([\&\%\|\+&a-z0-9_=,\:\;\.-]*)([\!\#\/\&\%\|\+a-z0-9_=,\:\;\.-]*)}*/i"; $imageregex = "/<img(.*?)src=(\"|\')(.+?)(gif|jpg|png|bmp)(\"|\')(.*?)(\/)?>(<\/img>)?/"; $imageprefixregex = "/\.(jpg|png|gif|bmp)$/i"; $pattern_youtube = '#\b(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})[^\s,]*#x'; preg_match_all( $urlregex, $content, $allstars ); if($allstars) { require_once(apfpath . '/lib/opengraph.php'); foreach( $allstars[0] $key => $star ) { if (preg_match($imageprefixregex, $star)) { // first check if image $markup = '![img]('.$star.'){.class}'; $content = str_replace( $star, $markup, $content ); } else if (preg_match($pattern_youtube, $star, $match)) { // else if test youtube link $graph = opengraph::fetch($star); $markup = '[![img](http://img.youtube.com/vi/'.$match[1].'/0.jpg)](http://youtu.be/'.$match[1].' "'.$graph->title.'"){#'.$match[1].' .ytmarkdown}'; $content = str_replace( $star, $markup, $content ); } else if(2 == 4) { // reserved local links } else { // else check if external link $graph = opengraph::fetch($star); $markup = '[![img]('.$graph->image.')**'.$graph->title.'** '.$graph->description.']('.$star.' "'.$star.'"){.graphmarkdown}'; $content = str_replace( $star, $markup, $content ); } } } //return json_encode($allstars); return $content; }
the idea convert services markdown
before parsing markdown extra.
problem str_replace
. example consider case when user input is:
https://www.youtube.com/watch?v=wxsv37gy1iu&feature=share https://www.youtube.com/watch?v=wxsv37gy1iu&feature=share http://youtu.be/wxsv37gy1iu
since first replace $content
oput be:
"[![img](http://img.youtube.com/vi/wxsv37gy1iu/0.jpg)]([![img](http://img.youtube.com/vi/wxsv37gy1iu/0.jpg)](http://youtu.be/wxsv37gy1iu "project gooseberry - why should contribute it?"){#wxsv37gy1iu .ytmarkdown} "project gooseberry - why should contribute it?"){#wxsv37gy1iu .ytmarkdown} [![img](http://img.youtube.com/vi/wxsv37gy1iu/0.jpg)]([![img](http://img.youtube.com/vi/wxsv37gy1iu/0.jpg)](http://youtu.be/wxsv37gy1iu "project gooseberry - why should contribute it?"){#wxsv37gy1iu .ytmarkdown} "project gooseberry - why should contribute it?"){#wxsv37gy1iu .ytmarkdown} [![img](http://img.youtube.com/vi/wxsv37gy1iu/0.jpg)](http://youtu.be/wxsv37gy1iu "project gooseberry - why should contribute it?"){#wxsv37gy1iu .ytmarkdown} "
as can see replaced strings inserted previously.
when should return string this:
"[![img](http://img.youtube.com/vi/wxsv37gy1iu/0.jpg)](http://youtu.be/wxsv37gy1iu "project gooseberry - why should contribute it?"){#wxsv37gy1iu .ytmarkdown} [![img](http://img.youtube.com/vi/wxsv37gy1iu/0.jpg)](http://youtu.be/wxsv37gy1iu "project gooseberry - why should contribute it?"){#wxsv37gy1iu .ytmarkdown} [![img](http://img.youtube.com/vi/wxsv37gy1iu/0.jpg)](http://youtu.be/wxsv37gy1iu "project gooseberry - why should contribute it?"){#wxsv37gy1iu .ytmarkdown} "
i dont want disallow entering same link multiple times.
question is: there way tell want replace $star (link)
exactly?
sorry delay, have answer looking for. using php's built in function preg_replace_callback
instead of str_replace
. main difference iterates on each match , applies function match, replaces in string. can manipulate different parts of string (like 11-digit youtube id) , replace entire match whatever want.
in order apply this, though, had make structural changes code. first, moved variables containing various regex definitions outside of link_to_opengraph
function. include them parameters function later.
the first part of script looks this:
<?php // define content test on $content = 'lorem ipsum dolor sit amet, consectetur adipisicing elit, sed eiusmod tempor incididunt ut labore et dolore magna https://www.youtube.com/watch?v=wxsv37gy1iu&feature=share aliqua. ut enim ad minim veniam, <img src="http://www.google.com/images/logo.gif"> quis nostrud exercitation ullamco https://www.youtube.com/watch?v=wxsv37gy1iu&feature=share laboris nisi ut aliquip ex ea commodo consequat. duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. excepteur sint occaecat cupidatat non proident, sunt in culpa qui http://youtu.be/wxsv37gy1iu officia deserunt mollit anim id est laborum.'; // define regex expressions - don't appear need urlregex more $urlregex = "~(?:https?://|\s)[-a-z0-9]+(?:\.[-a-z0-9]+)*(?:\.[a-z]{2,4})(?:/+[-a-z0-9_.:;]*)*(?:\?[-&%|+a-z0-9_=,.:;]*)?(?:[-&%|+&a-z0-9_=,:;.]*)(?:[-!#/&%|+a-z0-9_=,:;.]*)}*~i"; $imageregex = '<img(.*?)src=("|\')(.+?)(gif|jpg|png|bmp)("|\')(.*?)(/)?>(</img>)?'; $imageprefixregex = "/\.(jpg|png|gif|bmp)$/i"; $pattern_youtube = '\bhttps?://(?:www\.)?(?:youtube\.com/[-a-z0-9]*?(?:\?|&)v=|youtu\.be/)([-a-z0-9]{11})[-a-z0-9&=]*?(?=\s|$)';
note: ended having rewrite $pattern_youtube
expression because whatever reason couldn't 1 had work code.
okay, next defined callback function , assigned variable named $callback_function
. function handle if/else blocks, opposed how done in link_to_opengraph
function. notice parameter $m
passed automatically function , contain each match. attach $imageregex
, $pattern_youtube
variables function use
keyword. variables available in function scope.
$callback_function = function($m) use ($imageregex, $pattern_youtube) { if (preg_match('~'.$pattern_youtube.'~i', $m[0])) { //$graph = opengraph::fetch($m[10]); $graph = '<font color=red>'.$m[10].'</font>'; // make dummy graph variable $replacement = '<br><br>[![img](http://img.youtube.com/vi/'.$m[10].'/0.jpg)](http://youtu.be/'.$m[10].' "'.$graph.'"){#'.$m[10].' .ytmarkdown}'; } else { $replacement = '<br><br><font color=blue>bubba gump</font>'; } return $replacement; };
next, print out $content
returned link_to_opengraph
function. function takes additional parameters regex expressions , callback function.
print link_to_opengraph($content, $callback_function, $imageregex, $pattern_youtube);
finally, have link_to_opengraph
function. function ends doing calling preg_replace_callback
, returning results.
function link_to_opengraph($content, $callback_function, $imageregex, $pattern_youtube) { $content = preg_replace_callback('~('.$imageregex.'|'.$pattern_youtube.')~i', $callback_function, $content); return $content; }
another thing different here evaluate both of patterns here @ once. callback function apply markup on own.
Comments
Post a Comment