Mark Baker Posted September 8, 2009 Share Posted September 8, 2009 I'm trying to use a preg_replace for some templating: The content that I have is structured like: $content = '[[firstname]] [[lastname]], You are a[[$$old//]]n[[//old$$]] [[$$old//]]old[[//old//]]young[[//old$$]] [[$$male//]][[//$$male//]]wo[[//male$$]]man'; where simply named fields in double square brackets are a straight subtitution (not a problem); but "fields" enclosed like [[$$old//]] are an "if test" with [[$$old//]] equating to "if ($old == 'Y')", the optional [[//old//]] corresponding to "else" and [[//old$$]] to end the if test. Content between the "merge" fields is to be used depending on the result of the "if" test. Currently my code is as follows: $content = '[[firstname]] [[lastname]], You are a[[$$old//]]n[[//old$$]] [[$$old//]]old[[//old//]]young[[//old$$]] [[$$male//]][[//$$male//]]wo[[//male$$]]man'; echo '<H3>Content</H3><pre>'; echo $content; echo '</pre><hr /><hr />'; function setMergeFields($strBody,$mergeData) { foreach($mergeData as $mergeKey => $mergeValue) { $mergeFrom[] = "/\[\[".$mergeKey."\]\]/Ui"; $mergeTo[] = $mergeValue; } $initialMerged = preg_replace($mergeFrom, $mergeTo, $strBody); foreach($mergeData as $mergeKey => $mergeValue) { echo '<h4>'.$mergeKey.'</h4>'; echo '<h5>ifelse Test</h5>'; preg_match_all('/\[\[\$\$'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$\]\]/Ui', $initialMerged, $dynamicMergeFields, PREG_SET_ORDER); echo '<pre>'; print_r($dynamicMergeFields); echo '</pre><br />'; if ($mergeValue == 'Y') { $initialMerged = preg_replace('/\[\[\$\$'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$\]\]/Ui', '$1', $initialMerged); } else { $initialMerged = preg_replace('/\[\[\$\$'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$\]\]/Ui', '$2', $initialMerged); } echo '<pre>'; echo $initialMerged; echo '</pre><hr />'; echo '<h5>if only Test</h5>'; preg_match_all('/\[\[\$\$'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$]\]/Ui', $initialMerged, $dynamicMergeFields, PREG_SET_ORDER); echo '<pre>'; print_r($dynamicMergeFields); echo '</pre><br />'; if ($mergeValue == 'Y') { $initialMerged = preg_replace('/\[\[\$\$'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$]\]/Ui', '$1', $initialMerged); } else { $initialMerged = preg_replace('/\[\[\$\$'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$]\]/Ui', '', $initialMerged); } echo '<pre>'; echo $initialMerged; echo '</pre><hr />'; } return $initialMerged; } // function setMergeFields() $mergefields = array( 'firstname' => 'Mark', 'lastname' => 'Baker', 'male' => 'Y', 'old' => 'Y' ); $merged = setMergeFields($content,$mergefields); echo '<h3>Final Result:</h3>'; echo '<pre>'; echo $merged; echo '</pre>'; echo '<hr />'; $mergefields = array( 'firstname' => 'Toni', 'lastname' => 'Baker', 'male' => 'N', 'old' => 'Y' ); $merged = setMergeFields($content,$mergefields); echo '<h3>Final Result:</h3>'; echo '<pre>'; echo $merged; echo '</pre>'; echo '<hr />'; $mergefields = array( 'firstname' => 'Rachael', 'lastname' => 'Baker', 'male' => 'N', 'old' => 'N' ); $merged = setMergeFields($content,$mergefields); echo '<h3>Final Result:</h3>'; echo '<pre>'; echo $merged; echo '</pre>'; echo '<hr />'; The three tests in this sample code should return: Mark Baker, You are an old man Toni Baker, You are an old woman Rachael Baker, You are a young woman but actually return Mark Baker, You are an[[//old$$]] [[$$old//]]old [[//$$male//]]woman Toni Baker, You are an[[//old$$]] [[$$old//]]old man Rachael Baker, You are ayoung man There seem to be two problems: When I do the ifelse preg_match for [[$$male//]][[//$$male//]]wo[[//male$$]] the regular expression doesn't find anything The if only preg_match for [[$$old//]]n[[//old$$]] [[$$old//]]old[[//old//]]young[[//old$$]] seems to greedily pick the whole block rather than just the first [[$$old//]]n[[//old$$]] This may be because the ifelse for [[$$old//]]old[[//old//]]young[[//old$$]] has failed Any help gratefully appreciated Quote Link to comment Share on other sites More sharing options...
Mark Baker Posted September 8, 2009 Author Share Posted September 8, 2009 First problem identified, not with the regexp but with my test content. Should have been: $content = '[[firstname]] [[lastname]], You are a[[$$old//]]n[[//old$$]] [[$$old//]]old[[//old//]]young[[//old$$]] [[$$male//]][[//male//]]wo[[//male$$]]man'; This now gives me: Mark Baker, You are an[[//old$$]] [[$$old//]]old man Toni Baker, You are an[[//old$$]] [[$$old//]]old woman Rachael Baker, You are ayoung woman Still having problems with the second "greedy" old test Quote Link to comment Share on other sites More sharing options...
Mark Baker Posted September 22, 2009 Author Share Posted September 22, 2009 Finally struggled through, and found something that appears to work for all my test cases. Posted here for the benefit of anybody else that may have a similar problem (particularly useful for templating). $content1 = '[[firstname]] [[lastname]], You are a[[$$old//]]n[[//old$$]] [[$$old//]]old[[//old//]]young[[//old$$]] [[$$male//]][[//male//]]wo[[//male$$]]man'; $content2 = '[[firstname]] [[lastname]] [[$$male//]]You are a[[$$old//]]n[[//old$$]] [[$$old//]]old[[//old//]]young[[//old$$]] man[[//male//]]You are a[[$$old//]]n[[//old$$]] [[$$old//]]old[[//old//]]young[[//old$$]] woman[[//male$$]] '; echo '<H3>Content1</H3><pre>'; echo $content1; echo '</pre><hr />'; echo '<H3>Content2</H3><pre>'; echo $content2; echo '</pre><hr /><hr />'; function setMergeFields($strBody,$mergeData) { echo '<b>Merge Fields</b><pre>'; print_r($mergeData); echo '</pre><hr />'; foreach($mergeData as $mergeKey => $mergeValue) { $mergeFrom[] = "/\[\[".$mergeKey."\]\]/Ui"; $mergeTo[] = $mergeValue; } $initialMerged = preg_replace($mergeFrom, $mergeTo, $strBody); foreach($mergeData as $mergeKey => $mergeValue) { if ($mergeValue == 'Y') { $initialMerged = preg_replace('/\[\[\$\$'.$mergeKey.'\/\/\]\](((?!\[\[\/\/'.$mergeKey.'\$\$\]\]).)*)\[\[\/\/'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$\]\]/Usi', '$1', $initialMerged); } else { $initialMerged = preg_replace('/\[\[\$\$'.$mergeKey.'\/\/\]\](((?!\[\[\/\/'.$mergeKey.'\$\$\]\]).)*)\[\[\/\/'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$\]\]/Usi', '$3', $initialMerged); } if ($mergeValue == 'Y') { $initialMerged = preg_replace('/\[\[\$\$'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$]\]/Usi', '$1', $initialMerged); } else { $initialMerged = preg_replace('/\[\[\$\$'.$mergeKey.'\/\/\]\](.*)\[\[\/\/'.$mergeKey.'\$\$]\]/Usi', '', $initialMerged); } } return $initialMerged; } // function setMergeFields() $mergefields = array( array( 'firstname' => 'Mark', 'lastname' => 'Baker', 'male' => 'Y', 'old' => 'Y' ), array( 'firstname' => 'Toni', 'lastname' => 'Baker', 'male' => 'N', 'old' => 'Y' ), array( 'firstname' => 'Rachael', 'lastname' => 'Baker', 'male' => 'N', 'old' => 'N' ) ); foreach ($mergefields as $mergefieldSet) { $merged = setMergeFields($content1,$mergefieldSet); echo '<h3>Content 1 - Final Result:</h3>'; echo '<pre>'; echo $merged; echo '</pre>'; echo '<hr />'; $merged = setMergeFields($content2,$mergefieldSet); echo '<h3>Content 2 - Final Result:</h3>'; echo '<pre>'; echo $merged; echo '</pre>'; echo '<hr />'; } Quote Link to comment 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.