Jump to content

[SOLVED] if/else/endif preg_replace problems


Mark Baker

Recommended Posts

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

 

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

  • 2 weeks later...

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 />';
}

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.