Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String replace throws error with $ sign

Tags:

java

string

regex

I'm having an issue with replacing a string in java...

the line is:

subject = subject.replaceAll("\\[calEvent\\]", calSubject);

This line doesn’t work with $ sign in calSubject.

what the subject variable is, a dynamic subject line variable from a file. for example like so: Calnot = [calEvent]

what i am trying to do is replace the calEvent place holder with the subject variable. but how i did it does not work because it crashes when the subject contains a $ sign.

any idea how I can do this so it won't break if the subject contains a $ sign or any characters for that matter?

like image 210
OakvilleWork Avatar asked Apr 15 '13 15:04

OakvilleWork


2 Answers

That's because the dollar sign is a special character in a replacement string, use Matcher.quoteReplacement() to escape this kind of character.

subject = subject.replaceAll("\\[calEvent\\]", Matcher.quoteReplacement(calSubject));

From the doc of String.replaceAll() :

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.

Note that the dollar sign is used to refer to the corresponding capturing groups in the regular expression ($0, $1, etc.).

EDIT

Matcher.quoteReplacement() has been introduced in Java 1.5, if you're stuck in Java 1.4 you have to escape $ manually by replacing it with \$ inside the string. But since String.replaceAll() would also take the \ and the $ as special characters you have to escape them once and you also have to escape all \ once more for the Java runtime.

("$", "\$") /* what we want */
("\$", "\\\$") /* RegExp engine escape */
("\\$", "\\\\\\$") /* Java runtime escape */

So we get :

calSubject = calSubject.replaceAll("\\$", "\\\\\\$");  
like image 85
zakinster Avatar answered Sep 27 '22 16:09

zakinster


if you don't need the regex feature, you can consider to use this method of String class: replace(CharSequence target,CharSequence replacement)

It saves your "escape" backslashes as well.

api doc:

Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence. The replacement proceeds from the beginning of the string to the end, for example, replacing "aa" with "b" in the string "aaa" will result in "ba" rather than "ab".

like image 40
Kent Avatar answered Sep 27 '22 18:09

Kent