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
https://forums.phpfreaks.com/topic/149511-preg_replace-but-not-when-within-quotes/
Share on other sites

You need to be able to check what's around it without actually matching anything, so that the other instances will be able to have something to match against.  Lookaround to the rescue!

 

$string = preg_replace('~(?<!"\w ){ (\w) }(?! \w")~',"X $1 Y",$string);

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.