|
This behavior isn't so unexpected after reading the documentation, which states:
"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. Dollar signs may be treated as references to captured subsequences as described above, and backslashes are used to escape literal characters in the replacement string."
The fact that dollar-sign references are available in the replacement String indicates that the replacement string is processed by the regex engine before the replacement is made. As with all Java String literals that are parsed by the regex engine, backslashes must be doubly-escaped, once for the Java compiler and again for the regex engine.
(I'll omit the literal-delimiting double-quotes for clarity.) In your example, the literal \"TEST\" becomes "TEST" when compiled by Java. The double-quote is not a special regex character, so it is unchanged by the regex engine before the replacement is made.
If you want the final result to be \"TEST\", your replacement string must be \\\\\"TEST\\\\\". When Java compiles the String, it is stored internally as \\"TEST\\". After the regex engine parses the string, it becomes \"TEST\" before it is appended as the replacement in the output string.
Users should know that this in not a bug. If all you need is character-for-character String matches, the apache method may be for you. But, if you need more powerful regex matches in the search string, or $ references in the replacement string, the apache method won't cut it.
|
New method String.replace(CharSequence, CharSequence)
is a drop-in fix for replaceAll which performs a literal replacement. (A String is a CharSequence)
To performa literal replaceFirst, use:
s.replaceFirst(Pattern.quote("text to replace"), Matcher.quoteReplacement("replacement text"));