margaux Posted May 2, 2013 Share Posted May 2, 2013 I'm having a little trouble with preg_replace. The aim is to take a shortcode and replace it with some html code. The shortcode is of the format [image file=name.ext]. Each instance of the shortcode in some content should be replaced with <img src="path/to/images/name.ext" alt="name image" /> What is actually happening is the shortcode is being replaced with [<img src="path/to/images/name.ext" alt="name image" />] Printing out the relevant array shows no brackets so not sure where to look to solve this. Also can preg_match be used to find more than one occurrence of a pattern? The php manual indicates yes, but my testing was only coming up with one occurrence so I've resorted to using preg_match_all. Here's my test file with some content if you want to test it out. As ever please suggest any improvements. Thanks. define ('BASE_URL', '/path/to/root/'); $content = '<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p> [image file=file1.jpg]<h3>Ipsem</h3> <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p> [image file=file2.jpg]<h3>Lorem</h3> <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. </span>ipsem lorem blah di blah.</span>'; $html_content=replace_shortcodes($content); echo( $html_content); function replace_shortcodes($content){ $html_array=array(); $shortcodes = get_all_shortcodes($content); foreach ($shortcodes as $shortcode) { $filename = get_sc_attr($shortcode); $alt = substr($filename, 0, strpos($filename,'.')); $html_array[]='<img src="' . BASE_URL . 'images/' . $filename . '" alt="'. $alt. ' image" />'; } $html_content= preg_replace($shortcodes, $html_array, $content); return $html_content; } function get_all_shortcodes($content){ $sc_regex = '/\[\s*image\s+file\s*=\s*[\w-]+\.[\w-]+\s*\]/'; preg_match_all($sc_regex, $content, $matches); return $matches[0]; } function get_sc_attr($shortcode) { $length = (strpos($shortcode,']') - strpos($shortcode,'=')); $filename = trim(substr($shortcode, strpos($shortcode,'=') +1,$length-1)); return $filename; } Link to comment Share on other sites More sharing options...
HartleySan Posted May 3, 2013 Share Posted May 3, 2013 Also can preg_match be used to find more than one occurrence of a pattern? The php manual indicates yes, but my testing was only coming up with one occurrence so I've resorted to using preg_match_all. Where in the PHP manual does it say this? I'm pretty sure that preg_match stops after the first match (although you can set an offset to affect from where in the subject string the first match is found). As you stated, you have to use preg_match_all to do a global (i.e., multimatch) search. Now, with that said, in your case, you can probably do the whole search and replace in one line of code using the preg_replace function and backreferences. The following is some code that demonstrates what I would do to solve your problem: <?php define('BASE_URL', '/path/to/root/'); $str = 'The following are two really cool images: [image file=big_kahuna.jpg] [image file=solar_flare.png] And here\'s one more inline image ([image file=webgl.gif]) just because.'; echo "<b>Original text with shortcodes:</b><br><pre>$str</pre><br><br>"; echo "<b>New text with HTML img tags:</b><br><pre>" . htmlentities(preg_replace('/\[\s*image\s+file\s*=\s*([\w-]+)\.([\w-]+)\s*\]/', '<img src="' . BASE_URL . 'images/$1.$2" />', $str)) . '</pre>'; The $1 and $2 in the second argument of the preg_replace function are the backreferences. They refer to the [\w-]+ parts of the regex within the two sets of parentheses. (If you'll recall from your other recent topic on regexes, I mentioned that one of the two uses of parentheses in regexes is to create backreferences.) As a final comment, note that I had to use both pre tags and the htmlentities function to make the before and after code viewable on the screen. For an actual application, neither would be required. Please let me know if you have any other questions. Thanks. 2 Link to comment Share on other sites More sharing options...
margaux Posted May 3, 2013 Author Share Posted May 3, 2013 Thanks HartleySan - that's a very nice solution to what I was trying to do. I appreciate you taking the time to explain it as I understand the preg functions better now. I misunderstood the manual and was thinking that the 3rd argument was an array collecting all the matches, but its for collecting full and partial matches. Link to comment Share on other sites More sharing options...
Recommended Posts