Tuesday, 15 April 2014

java replaceFirst problem with $

Not here, it isn't. When calling replaceFirst() or replaceAll(), the first argument is a regular expression, which follows the rules of java regular expressions as described in java.util.regex.Pattern. But the second argument is not a regex; it's a replacement text - which has different rules. Quoting from the String.replaceFirst() API: "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.replaceFirst(java.lang.String). Use Matcher.quoteReplacement(java.lang.String) to suppress the special meaning of these characters, if desired."

If you follow the link to Matcher.replaceFirst() it refers you to Matcher.appendReplacement() which has more detail: "The replacement string may contain references to subsequences captured during the previous match: Each occurrence of $g will be replaced by the result of evaluating group(g). The first number after the $ is always treated as part of the group reference. Subsequent numbers are incorporated into g if they would form a legal group reference. Only the numerals '0' through '9' are considered as potential components of the group reference. If the second group matched the string "foo", for example, then passing the replacement string "$2bar" would cause "foobar" to be appended to the string buffer. A dollar sign ($) may be included as a literal in the replacement string by preceding it with a backslash (\$)."

In other words, $1 would be capture group 1, $6 would be capture group 6. $z doesn't make sense to the matcher - that's what "Illegal group reference" means here. Because z is not a group.

And to fix this problem, you can either do as EFJ showed, putting a double backslash in front of the $, or you can use Matcher.quoteReplacement() as suggested in the replaceFirst() API:

String y = Matcher.quoteReplacement("xy$z");


Now What we do in this case : String x ="${data} m,.m,.m,";

So the solution is :


        String x ="${data} m,.m,.m,";
        String y = x.replaceFirst("\\$\\{data\\}", "Amaan");
        System.out.println(y); 
Post a Comment