12

I am using preg_replace to escape special characters:

$tmpStr=preg_replace("/\?/", "\?", $tmpStr);
$tmpStr=preg_replace("/\#/", "\#", $tmpStr);
$tmpStr=preg_replace("/\^/", "\^", $tmpStr);
$tmpStr=preg_replace("/\&/", "\&", $tmpStr);
$tmpStr=preg_replace("/\*/", "\*", $tmpStr);
$tmpStr=preg_replace("/\(/", "\(", $tmpStr);
$tmpStr=preg_replace("/\)/", "\)", $tmpStr);
$tmpStr=preg_replace("/\//", "\/", $tmpStr); 

But I am not able to escape $ using the same function:

$tmpStr=preg_replace("/\$/", "\$", $tmpStr);

And also when I use the above statement all the spaces get replaced by $ and $ is not getting escaped.

How do I escape the dollar sign correctly?

Alan Moore
  • 73,866
  • 12
  • 100
  • 156

10 Answers10

14

I would strongly recommend using preg_quote() instead.

soulmerge
  • 73,842
  • 19
  • 118
  • 155
  • 1
    I would find this answer more helpful if it gave the rationale for using preg_quote instead of preg_replace. Also, it would be nice to know why the preg_replace approach didn't work for escaping the dollar sign. – Syntax Junkie Oct 19 '16 at 20:52
  • 1
    @RandallStewart "preg_quote instead of preg_replace"? Those two functions are not replaceable, you can't use one instead of the other, you use `preg_quote` to escape values in regular expression strings (used inside of `preg_replace`) – Brian Leishman Jul 27 '17 at 20:05
  • This will produce bugs in other places. For example `‌‌preg_replace('/\{\s*price\s*\}/', preg_quote('$100.00'), 'it cost {price}');` will return `‌it cost $100\.00` instead of the expected `‌it cost $100.00` – Peter Ajtai May 09 '18 at 23:12
  • 2
    @PeterAjtai: I think you misunderstood the purpose of `preg_quote()`: It is not for the *second* parameter of `preg_replace()`, but for the *first*. Please re-read the question and the documentation of `preg_quote()` (the second example might be especially useful for fully understanding the issue at hand) – soulmerge May 14 '18 at 07:23
  • Thanks @soulmerge I see the difference. – Peter Ajtai May 15 '18 at 03:41
  • This can not be used in conjuction with ```preg_replace``` as it leaves slashes in front of other special chars. – Rik Verbeek Nov 15 '22 at 10:23
9

The correct answer is that you must escape the backslash and the dollar sign in the regex using PHP's escape characters.

backslash = \\
dollar sign = \$

$tmpStr=preg_replace("/\\\$/", "\\$", $tmpStr);

This is useful for anyone that needs to match a string that contains a dollar sign.

Sal
  • 191
  • 1
  • 2
  • 1
    I think this should be the correct answer to the question also with the explanation, because in my case also preg_quote had a problem with replacing with the dollar sign and this double escaped version solved it. – Mochi Jun 22 '20 at 12:14
5

Looks like your problem is one of escaping. Single quotes (') in PHP work differently than double quotes ("). It's a lot like in Perl, where variable interpolation does not happen in singly-quoted strings, and the dollar sign ($) is not a meta-character:

print "\$"; # prints $
print '\$'; # prints \$

Also, Perl's character classes will simplify your code:

$tmpStr = preg_replace('/([?#^&*()$\\/])/', '\\\\$1', $tmpStr);
amphetamachine
  • 27,620
  • 12
  • 60
  • 72
4

The $ sign has to be escaped with itself so

$tmpStr=preg_replace("/$$/", "\$", $tmpStr);

I would also advise to look to addslashes instead.

Peter Smit
  • 27,696
  • 33
  • 111
  • 170
2

Yes, it does seem that \\$ is seen by PHP as $ in a double-quoted string. That means you have to make PHP see a \$ by saying \\\$ .

I just tried preg_replace("/\\\$$k\\\$/", $v, $data) and indeed it works (replaces occurrences of $KEY$ with VALUE.

j0k
  • 22,600
  • 28
  • 79
  • 90
katushkin
  • 21
  • 2
0

IIRC you replace $ with $. So it should be $$

You can also try

$tmpStr=preg_replace('/\$/', '\$', $tmpStr);
Ólafur Waage
  • 68,817
  • 22
  • 142
  • 198
0

isn't it true that PHP sees \$ as $ ? I haven't tested this out, it might go like this;

php is first, and replaces your "/\$/" with "/$/" then the preg engine does it's magic .. unfortunately, $ is a regular expression operator ( I believe it matches the end of a string?), so it doesn't find the $-characters in your text but will

I think, what you need to do, is to doubble escape the $-character like so;

$tmpStr=preg_replace("/\$/", "\$", $tmpStr);

Also .. in this case, I would have just used str_replace()

Jake
  • 3,973
  • 24
  • 36
-1
$pattern = preg_replace('/\$(.+)/', '\\\$$1', $pattern);
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
mMo
  • 233
  • 2
  • 10
  • Could you add some details regarding your code and it how addresses the problem(s) in the question? Code only answers are not very useful, especially for future readers that stumble upon this post. Thanks, – Cristik Mar 17 '16 at 08:06
-2

In PHP, for the particular case of "$" used in HTML, you can also do a previous replace for its entity:

$tmpStr = str_replace('$', '$',$tmpStr);
lennon310
  • 12,503
  • 11
  • 43
  • 61
Germán
  • 1
  • 1
-2

Try a addslashes() ?

Check php.net / addslashes()

KingRider
  • 2,140
  • 25
  • 23