Jump to content

preg_replace and $


fivestringsurf
Go to solution Solved by requinix,

Recommended Posts

I've been working on my own templating feature in which a page of static html is replaced by php variables when they exist.  When $  (dollar sign) exists on the static page before the templating magic it is getting omitted when i replace things using preg_replace() for the output.

This simple example illustrates this:

	$price = '$10.99';
	$template = 'Your cost: $price';
	$output = preg_replace('/\$price/', $price, $template);
	echo $output; //Your cost: .99

notice the "$" is now missing from output.

Anyone know how to solve this problem and preserve dollar signs in an elegant way.

I know I can do something like $price = str_replace('$', '\$', $price); but that seems ugly and simply another string function that isn't necessary. (I'm already using a lot of resources to make the templating feature work)

 

Note:  I'm using php ver. 5.2

I thought maybe preg_replace_callback() might work but it doesn't seem to be supported

Link to comment
Share on other sites

  • Solution

Since you're not actually using regular expressions, str_replace() or strtr (with an array) is better.

 

Anyway, the problem is preg_replace() thinks the "$10" in the replacement string is supposed to be a back-reference to the tenth captured substring. Since there isn't one it uses an empty string.

$price = addcslashes('$10.99', '$\\');
[edit] preg_replace_callback() should be supported but you'd have to use create_function (if you wanted the function inline), which is a really ugly and bug-prone way of doing it - an actual function somewhere would be better.

 

[edit 2] If you're replacing variables, consider doing a preg_replace() or preg_replace_callback() that simply looks for all things that look like variables, checks if the matched variable exists in some master list (you shouldn't just allow any variable at all), and if so replace with the variable's value. Something like

function replaceVariables($string, array $variables) {
	return preg_replace(
		'/(?<=\$)[a-z_][a-z0-9_]*/ei',
		'isset($variables["$0"]) ? $variables["$0"] : "\$$0"', // check that escaping there, might not work
		$string
	);
}
(which uses /e, yes, but that's not deprecated until 5.5 and using it is easier than preg_replace_callback() with create_function()). If you really wanted to allow for all variables, which I'll say again is a bad idea that you should seriously reconsider, then you can just pass $GLOBALS:

$out = replaceVariables($in, $GLOBALS);
Edited by requinix
Link to comment
Share on other sites

first off, thanks for taking the time to provide an explanation!  your explanation about "back-reference to the tenth captured substring"... perfect.  forgot about that - duh.  and you're exactly right about using str_replace().  Not only did str_replace() solve my debacle, it should be way faster too.   win/win for my application.

Thanks again!

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.