¿Por qué replaceAll falla con “referencia de grupo ilegal”?

Estoy en necesidad de reemplazar

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

solía

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

pero arroja una excepción

java.lang.IllegalArgumentException: referencia de grupo ilegal

Use "\\$\\$" en el segundo parámetro:

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

El símbolo de $ es grupo en el parámetro de reemplazo de regex

Entonces necesitas escapar de eso

De String # replaceAll javadoc :

Tenga en cuenta que las barras diagonales inversas (\) y los signos de dólar ($) en la cadena de reemplazo pueden causar que los resultados sean diferentes a si se tratara como una cadena de reemplazo literal; ver Matcher.replaceAll. Utilice Matcher.quoteReplacement (java.lang.String) para suprimir el significado especial de estos caracteres, si lo desea.

Por lo tanto, se puede escapar de una cadena de reemplazo arbitraria usando Matcher # quoteReplacement :

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

También se puede escapar del patrón con Pattern # quote

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

El problema aquí no es la expresión regular, sino la sustitución:

$ se usa para referirse a () grupos coincidentes. Por lo tanto, debe escapar también con una barra diagonal inversa (y una segunda barra diagonal inversa para que el comstackdor de Java esté contento):

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

Esta es la manera correcta. Reemplace el $ literar por escape \\ $ str.replaceAll("\\$", "\\\\\\$")

$ tiene un significado especial en la cadena de reemplazo, así como en la expresión regular, por lo que debe escapar también allí:

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

Tuve el mismo problema, así que termino implementando reemplazar todo con split.
Solucionó la excepción para mí

 public static String replaceAll(String source, String key, String value){ String[] split = source.split(Pattern.quote(key)); StringBuilder builder = new StringBuilder(); builder.append(split[0]); for (int i = 1; i < split.length; i++) { builder.append(value); builder.append(split[i]); } while (source.endsWith(key)) { builder.append(value); source = source.substring(0, source.length() - key.length()); } return builder.toString(); }