2

Consider the below use of preg_replace

$str='{{description}}';
$repValue='$0.0 $00.00 $000.000 $1.1 $11.11 $111.111';

$field = 'description';
$pattern = '/{{'.$field.'}}/';

$str =preg_replace($pattern, $repValue, $str );
echo $str;


// Expected output: $0.0 $00.00 $000.000 $1.1 $11.11 $111.11
// Actual output:   {{description}}.0 {{description}}.00 {{description}}0.000 .1 .11 1.111 

Here is a phpFiddle showing the issue

It's clear to me that the actual output is not as expected because preg_replace is viewing $0, $0, $0, $1, $11, and $11 as back references for matched groups replacing $0 with the full match and $1 and $11 with an empty string since there are no capture groups 1 or 11.

How can I prevent preg_replace from treating prices in my replacement value as back references and attempting to fill them?

Note that $repValue is dynamic and it's content will not be know before the operation.

2
  • Are you sure you need to use preg_replace, not str_replace? Commented Oct 11, 2016 at 0:05
  • @Barmar , you're right, I could actually just use str_replace, thank you Commented Oct 11, 2016 at 0:42

1 Answer 1

5

Escape the dollar character before using a character translation (strtr):

$repValue = strtr('$0.0 $00.00 $000.000 $1.1 $11.11 $111.111', ['$'=>'\$']);

For more complicated cases (with dollars and escaped dollars) you can do this kind of substitution (totally waterproof this time):

$str = strtr($str, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']);
$repValue = strtr($repValue, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']);
$pattern = '/{{' . strtr($field, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']) . '}}/';
$str = preg_replace($pattern, $repValue, $str );
echo strtr($str, ['%%'=>'%', '$%'=>'$', '\\%'=>'\\']);

Note: if $field contains only a literal string (not a subpattern), you don't need to use preg_replace. You can use str_replace instead and in this case you don't have to substitute anything.

Sign up to request clarification or add additional context in comments.

3 Comments

No. Just specific preg_quote()
@Deep: no, preg_quote is only designed for patterns and is not appropriate for replacement strings (make the test)
Ou... for replacement. Sorry.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.