lfernando Posted February 25, 2014 Share Posted February 25, 2014 (edited) Looking for strings that start with <li and end with either value="pass">, value="fail"> or just >. I need to replace each of these strings with a different variable, and also the result must include whatever was in between the start and end of the string. I managed to do it, but I'm using three different preg_replace. Surely this can be done more efficiently in one single pre_replace. Any ideas? Thanks! $string=' <li id="5691_3" value="pass"> Some text here</li> <li id="5691_4" value="pass"> Some text here</li> <li id="5691_6"> Some text here</li> <li id="5691_7" value="fail"> Some text here</li> ' $varPass= "You passed! - "; $varFail = "You failed! - "; varBlank="Its blank! - "; $string= preg_replace('/<li ([^>]*) value="pass">/', '<br>Result for $1 ' . $varPass, $string) $string= preg_replace('/<li ([^>]*) value="fail">/', '<br>Result for $1 '.$varFail, $string) $string= preg_replace('/<li ([^>]*)>/', '<br>Result for $1 '.$varBlank, $string); $string=str_replace("</li>","",$string); // this results into... $string=' <br>Result for id="5691_3" - You passed! Some text here <br>Result for id="5691_4" - You passed! Some text here <br>Result for id="5691_6" - Its blank! Some text here <br>Result for id="5691_7" - You failed! Some text here ' Edited February 25, 2014 by lfernando Quote Link to comment https://forums.phpfreaks.com/topic/286523-can-you-combine-these-three-preg_replace-into-one/ Share on other sites More sharing options...
Psycho Posted February 25, 2014 Share Posted February 25, 2014 (edited) Use an array for the expressions and the replacements. I made some other improvements as well to account for other parameters being in the LI tags. Although it still requires that the id parameter comes before the value parameter. It could be written to work with them in any order, but I was too lazy too look up the format. $string=' <li id="5691_3" value="pass"> Some text hereA</li> <li id="5691_4" value="pass"> Some text hereB</li> <li id="5691_6"> Some text hereC</li> <li id="5691_7" value="fail"> Some text hereD</li> '; $patterns = array( '#<li.*?id="([^"]*)".*?value="pass"[^>]*>([^<]*)</li>#', '#<li.*?id="([^"]*)".*?value="fail"[^>]*>([^<]*)</li>#', '#<li.*?id="([^"]*)"[^>]*>([^<]*)</li>#' ); $replacements = array( 'Result for ID "$1" You passed! - $2<br>', 'Result for ID "$1" You failed! - $2<br>', 'Result for ID "$1" Its blank! - $2<br>' ); $string= preg_replace($patterns, $replacements, $string); echo $string; Output Result for ID "5691_3" You passed! - Some text hereA Result for ID "5691_4" You passed! - Some text hereB Result for ID "5691_6" Its blank! - Some text hereC Result for ID "5691_7" You failed! - Some text hereD Edited February 25, 2014 by Psycho Quote Link to comment https://forums.phpfreaks.com/topic/286523-can-you-combine-these-three-preg_replace-into-one/#findComment-1470653 Share on other sites More sharing options...
.josh Posted February 25, 2014 Share Posted February 25, 2014 Alternatively, you can use preg_replace_callback. However.. this would be better achieved with a DOM parser. For shits and grins, here is the preg_replace_callback version: $string=<<<EOC <li id="5691_3" value="pass"> Some text here</li> <li id="5691_4" value="pass"> Some text here</li> <li id="5691_6"> Some text here</li> <li id="5691_7" value="fail"> Some text here</li> EOC; $string = preg_replace_callback( '~<li[^>]*(id="[^"]+")(?:[^>]*value="([^"]+)")?[^>]*>(.*?)</li>~', function ($m) { $r = "<br>Result for {$m[1]} - "; $r.= (!empty($m[2]))? "You {$m[2]}ed!" : "It's blank!"; $r.= " {$m[3]}"; return $r; }, $string ); echo $string; I too will decline making this "fool proof" as far as order of attributes, spacing, etc.. because as I said, a DOM parser is better suited for this sort of thing. Quote Link to comment https://forums.phpfreaks.com/topic/286523-can-you-combine-these-three-preg_replace-into-one/#findComment-1470654 Share on other sites More sharing options...
requinix Posted February 25, 2014 Share Posted February 25, 2014 Speaking of DOM... It's definitely longer but it's more flexible than string matching. It's also a matter of principle: avoid using regular expressions on HTML. $html = <<<HTML ... <ul> <li id="5691_3" value="pass"> Some text here</li> <li id="5691_4" value="pass"> Some text here</li> <li id="5691_6"> Some text here</li> <li id="5691_7" value="fail"> Some text here</li> </ul> ... HTML; $dom = new DOMDocument(); $dom->loadHTML($html); $lis = $dom->getElementsByTagName("li"); for ($i = 0; $i < $lis->length; ) { // no $i++ $li = $lis->item($i); $parent = $li->parentNode; if ($li->getAttribute("value") == "pass") { $text = "You passed!"; } else if ($li->getAttribute("value") == "fail") { $text = "You failed!"; } else { $text = "It's blank!"; // $parent->removeChild($li); // continue; } $id = $li->getAttribute("id"); $text = "Result for id={$id} - {$text}{$li->nodeValue}"; $textnode = $dom->createTextNode($text); $parent->replaceChild($textnode, $li); $parent->insertBefore($dom->createElement("br"), $textnode); } echo $dom->saveHTML();Regarding $i: when removing nodes, like with removeChild() or replaceChild(), the node you had will be removed from everywhere. That includes $lis. So $i shouldn't advance beyond 0 because it'll always want to look at the first item in the list....unless you decide that a node shouldn't be removed, for whatever reason, in which case you $i++ and then continue. Quote Link to comment https://forums.phpfreaks.com/topic/286523-can-you-combine-these-three-preg_replace-into-one/#findComment-1470657 Share on other sites More sharing options...
lfernando Posted February 26, 2014 Author Share Posted February 26, 2014 Thank you for your help! Just curious, why avoid using regex on HTML? If it makes a dfference this HTML code is stored in a MYSQL database which im accessing via PHP. Quote Link to comment https://forums.phpfreaks.com/topic/286523-can-you-combine-these-three-preg_replace-into-one/#findComment-1470806 Share on other sites More sharing options...
.josh Posted February 26, 2014 Share Posted February 26, 2014 I supplied a link in my previous post that explains why you should avoid regex for html. I labeled it "DOM Parser" because the link also gives suggestions for DOM Parsers you can use. http://forums.phpfreaks.com/topic/273123-readme-php-regex-resources-faqs/?do=findComment&comment=1405513 Quote Link to comment https://forums.phpfreaks.com/topic/286523-can-you-combine-these-three-preg_replace-into-one/#findComment-1470809 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.