Aaron Johnson Now with 50% less caffeine!

Posted
9 February 2006 @ 3pm

Tagged
J2EE, Software Development

java.lang.IllegalArgumentException: Illegal group reference, replaceAll and dollar signs

This weblog is officially about inane things I run into while trying to do my job at work. Let’s say you have a String object like this:

String mystring = "Your password: #PASSWORD";

and at runtime you need to replace the value of #PASSWORD with a password that a user typed in. You’d write something like this:

String password = "$Jslwe"
mystring = mystring.replaceAll("#PASSWORD", password);

What would happen? You’d expect that the key #PASSWORD would get replaced with the value of the variable ‘password’ (which is “$Jslwe”) and then you’d move happily on your way to something much more interesting. But no, Java throws you an error:

java.lang.IllegalArgumentException: Illegal group reference

which is extremely helpful. Turns out that the second argument to the String replaceAll method “may” have some issues with dollar signs and backslashes which you only find out about if you dig into the Matcher class that backs the replaceAll method or if you’re lucky and you read about the whole thing on a site devoted to regular expressions. In short:

myString.replaceAll(”regex”, “replacement”) replaces all regex matches inside the string with the replacement string you specified. No surprises here. All parts of the string that match the regex are replaced. You can use the contents of capturing parentheses in the replacement text via $1, $2, $3, etc. $0 (dollar zero) inserts the entire regex match. $12 is replaced with the 12th backreference if it exists, or with the 1st backreference followed by the literal “2″ if there are less than 12 backreferences. If there are 12 or more backreferences, it is not possible to insert the first backreference immediately followed by the literal “2″ in the replacement text.

In the replacement text, a dollar sign not followed by a digit causes an IllegalArgumentException to be thrown. If there are less than 9 backreferences, a dollar sign followed by a digit greater than the number of backreferences throws an IndexOutOfBoundsException. So be careful if the replacement string is a user-specified string. To insert a dollar sign as literal text, use \$ in the replacement text. When coding the replacement text as a literal string in your source code, remember that the backslash itself must be escaped too: “\\$”.


18 Comments

Posted by
Ron
10 February 2006 @ 1am

Hmmmm, I like MessageFormat more for the problem as stated.


Posted by
Moritz
10 February 2006 @ 3am

Yepp. MessageFormat is the better choice here.


Posted by
Daniel
23 April 2006 @ 5am

Thanks a lot! Your short explanation probably saved me a couple of hours reading javadocs.


Posted by
Elifarley
10 May 2006 @ 10pm

I’d use StringKit’s ‘format’ method, as in the following example:

String mystring = “Your password: ?”;

Integer userCode = new Integer(5);

String password = “$Jslwe”

String newString = StringKit.format(mystring, userCode);
// newString is “Your password: 5″

String newString = StringKit.format(mystring, password);
// newString is “Your password: $Jslwe”

Map map = new HashMap();

map.put(”code”, new Integer(67));
map.put(”pw”, “$t*#@!$\”R12″);

String mystring = “Your password: ${pw}; code: ${code}”;

String newString = StringKit.format(mystring, map);
// newString is “Your password: $t*#@!$”R12; code: 67″

I just haven’t had the time to set up a site for StringKit, but I can provide you the source code if you want.

Regards,
Elifarley

elifarley a t Gmail d.o.t.com


Posted by
Victor
23 August 2006 @ 5am

// problem resolved by
// Matcher.quoteReplacement(password)

String mystring = “Your password: #PASSWORD”;
String password = “$Jslwe”;

password = Matcher.quoteReplacement(password);

mystring = mystring.replaceAll(”#PASSWORD”, password);


Posted by
sajid
27 October 2006 @ 1am

when we are trying to view the attachment file this error is occuring java.land.IllegalArgumentException:{stream type is mandatory} what is the cause of this error why it is occuring


Posted by
Sanjay V
27 October 2006 @ 5am

ajohnson /Victor

You are a life saver.


Posted by
Shrinivas
24 January 2007 @ 6am

A great big thank you…You have saved me about 3 hours of mind-numbing pain… I am grateful..no I am in your debt..!


Posted by
gen frosch
25 March 2007 @ 1pm

Thanks a lot! This was exactly what I needed to fix my proggy.
Greets from Germany!


Posted by
Googler
4 May 2007 @ 12am

Hi,

This saved my hours of efforts

Great work done

Thanks a million.

password = Matcher.quoteReplacement(password);


Posted by
zgibek
19 June 2007 @ 2am

Many thanks to ajonson and Victor.
best regards!


Posted by
Matt Snider
2 August 2007 @ 1pm

Many thanks. If I hadn’t found your post I probably would have been stuck on this for hours.


Posted by
Srividhya Sriram
30 August 2007 @ 5pm

Thanks a lot Mr. Victor

I have been trying out for a solution and i got it from your reply.
Saved me a lot of time.

// problem resolved by
// Matcher.quoteReplacement(password)


Posted by
LateNightDeveloper
1 September 2007 @ 6pm

Thank you Victor. That saved me hours!


Posted by
Teryk
4 February 2008 @ 7am

Thanks a lot ! Hours saved


Posted by
Doc
8 May 2008 @ 4pm

This could have taken me hours to work out. Thanks Victor!


Posted by
clawoo
11 June 2008 @ 6am

Thanks Aaron and Victor. Good catch!


Posted by
SARA
30 June 2008 @ 2am

THanks a lot Victor.


Leave a Comment

Links: 1-29-2006 Links: 2-9-2006