Why does replaceAll fail with "illegal group reference"?

I am in need to replace

\\\s+\\$\\$ to $$

I used

String s = "  $$";
s = s.replaceAll("\\s+\\$\\$","$$");

but it throws exception

java.lang.IllegalArgumentException: Illegal group reference


Solution 1:

From String#replaceAll javadoc:

Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string; see Matcher.replaceAll. Use Matcher.quoteReplacement(java.lang.String) to suppress the special meaning of these characters, if desired.

So escaping of an arbitrary replacement string can be done using Matcher#quoteReplacement:

String s = "  $$";
s = s.replaceAll("\\s+\\$\\$", Matcher.quoteReplacement("$$"));

Also escaping of the pattern can be done with Pattern#quote

String s = "  $$";
s = s.replaceAll("\\s+" + Pattern.quote("$$"), Matcher.quoteReplacement("$$"));

Solution 2:

Use "\\$\\$" in the second parameter:

String s="  $$";
s=s.replaceAll("\\s+\\$\\$","\\$\\$");
//or
//s=s.replaceAll("\\s+\\Q$$\\E","\\$\\$");

The $ is group symbol in regex's replacement parameter

So you need to escape it

Solution 3:

The problem here is not the regular expression, but the replacement:

$ is used to refer to () matching groups. So you need to escape it as well with a backslash (and a second backslash to make the java compiler happy):

String s="  $$";
s = s.replaceAll("\\s+\\$\\$", "\\$\\$");

Solution 4:

This is the right way. Replace the literar $ by escaped \\$ str.replaceAll("\\$", "\\\\\\$")