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

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.