那是因为美元符号是替换字符串中的特殊字符,Matcher.quoteReplacement()用于转义这种字符。
subject = subject.replaceAll("\\[calEvent\\]", Matcher.quoteReplacement(calSubject));
来自以下文档String.replaceAll():
请注意,替换字符串中的反斜杠 ( \) 和美元符号 ( $) 可能会导致结果与将其视为文字替换字符串时的结果不同;请参阅 Matcher.replaceAll。如果
Matcher.quoteReplacement(java.lang.String)需要,用于抑制这些字符的特殊含义。
请注意,美元符号用于指代正则表达式( 、 等)中的相应捕获$0组$1。
编辑
Matcher.quoteReplacement()已在 Java 1.5 中引入,如果您卡在 Java 1.4 中,则必须$通过将其替换\$为字符串内部来手动转义。但是因为String.replaceAll()也会将\and$作为特殊字符,所以您必须将它们转义一次,并且您还必须\为 Java 运行时再次转义所有字符。
("$", "\$") /* what we want */
("\$", "\\\$") /* RegExp engine escape */
("\\$", "\\\\\\$") /* Java runtime escape */
所以我们得到:
calSubject = calSubject.replaceAll("\\$", "\\\\\\$");