Jump to content

preg_replace, but not when within quotes


Mark Baker

Recommended Posts

I have a string in the format:

'1 { A } 2 { N } "B { 3 } C" 4 { 5 } 6 "E { 7 } F" 8 { G } 9 { H }'

and want to replace every occurrence of { with an X, and every occurrence of } with a Y, except when these values are within double quote marks, so the above example should give me:

'1 X A Y 2 X N Y "B { 3 } C" 4 X 5 Y 6 "E { 7 } F" 8 X G Y 9 X H Y'

 

I can do this using a normal str_replace() by exploding the string to an array on the double quote, and only replacing in odd numbered array entries, then imploding the string again.

$temp = explode('"',$input);
$i = 0;
foreach($temp as $key => $value) {
if (($i++ % 2) == 0) {
	$temp[$key] = str_replace($replaceFrom,$replaceTo,$value);
}
}
$result = implode('"',$temp);

 

However, while this gives me exactly what I need, it doesn't seem to be an efficient method; so I've been trying to work out a regexp that will locate each { or } within the string, count back the number of double quotes between that and the beginning of the string, and if it's an odd number do the replacement:

$pregReplaceFrom = array(
	'/^(.*\".*){0,2}\{/',
	'/^(.*\".*){0,2}\}/'
);
$pregReplaceTo = array(
	'$1X',
	'$1Y'
);

$result = preg_replace($pregReplaceFrom,$pregReplaceTo,$input);

However, this only replaces the last instances of { and } in my input, and adjusting {0,2} to {0,2,4,6,8} doesn't even replace that set... and doesn't seem a good way to do a count.

Similarly:

'/^(.*(\".*){0,2})\{/',

'/^(.*(\".*){0,2})\}/'

replaces the last set of braces only, and increasing the {0,2} results in no replacements. Ungreedy with {0,2} replaces the first set of braces only, and again increasing the {0,2} results in no replacements.

 

 

Is what I'm trying to achieve feasible using a single preg_replace? and if so, what am I doing wrong?

 

And is it likely to be a situation where my str_replace through the odd elements of an exploded string is the better approach anyway?

 

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.