aspose file tools*
The moose likes Java in General and the fly likes String replaceAll problem with $ Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "String replaceAll problem with $ " Watch "String replaceAll problem with $ " New topic
Author

String replaceAll problem with $

Bruce Jin
Ranch Hand

Joined: Sep 20, 2001
Posts: 666

String x = "aaa XXX bbb";
String replace = "XXX";
String y = "xy$z";
x = x.replaceFirst(replace, y);

Here y is a variable which may contain $.

$ in y caused error:
java.lang.IllegalArgumentException: Illegal group reference

How to handle $ here?

Thanks!


BJ - SCJP and SCWCD
We love Java programming. It is contagious, very cool, and lot of fun. - Peter Coad, Java Design

Crazy Bikes created by m-Power
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10354
    
    8

Originally posted by Bruce Jin:

Here y is a variable which may contain $.

$ in y caused error:
java.lang.IllegalArgumentException: Illegal group reference

How to handle $ here?

Thanks!


$ is treated as the end of line boundry matcher.
Take a look at the API for Pattern class. The replaceFirst(..) uses pattern matching internally. To quote from the replaceFirst(...) API
Replaces the first substring of this string that matches the given regular expression with the given replacement.


[How to ask questions] [Donate a pint, save a life!] [Onff-turn it on!]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24184
    
  34

... which means you have to use the "escape character" to tell the regular expression compiler to ignore the "$". You have to use a backslash, but since in a Java String a backslash is special, too, you have to use two backslashes to get a literal backslash into the String:

String y = "xy\\$z";


[Jess in Action][AskingGoodQuestions]
Bruce Jin
Ranch Hand

Joined: Sep 20, 2001
Posts: 666
Thanks.

How to escape a variable that may contain $?

y.replaceAll("\\$", "\\$");

would not work.

Thanks!
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Maneesh]: $ is treated as the end of line boundry matcher.

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:

[ September 24, 2007: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Bruce]: y.replaceAll("\\$", "\\$");

would not work.


In what way did it not work? What did you expect to happen, and what did happen? Offhand your example looks like it should do nothing at all.
Bruce Jin
Ranch Hand

Joined: Sep 20, 2001
Posts: 666
Thanks.

I am limited to JDK 1.4 so I can not use Matcher.quoteReplacement() witch is only in Jdk 1.5.

Since y is a variable I tried to escape it at runtime by using

y = y.replaceAll("\\$", "\\$");

But still y = "ab$xy" after this. $ is not escaped.

One way to handle this might be

y = y.replaceAll("\\$", "somejunk");

Then do other replace

Then do:

x = x.replaceAll("somejunk", "\$");

Thanks!
Kevin Baun
Greenhorn

Joined: Sep 24, 2007
Posts: 1
Originally posted by Bruce Jin:
Thanks.

How to escape a variable that may contain $?

y.replaceAll("\\$", "\\$");

would not work.

Thanks!


you 'do' realize that if you run the snippit as you have it here you are just replacing all the "$" with more "$".... right? Is there some other problem? have you tried to match against the hex value of the $ character?
Alan Moore
Ranch Hand

Joined: May 06, 2004
Posts: 262
Bruce Jin
Ranch Hand

Joined: Sep 20, 2001
Posts: 666
Thanks Alan.

That makes '$' '\$'!
amaan khanpro
Greenhorn

Joined: Oct 23, 2013
Posts: 1
String x="abc$$abc";
String y=x.replaceAll("\\$\\$", "Amaan");
System.out.println(y);
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38765
    
  23
Welcome to the Ranch
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: String replaceAll problem with $