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: “\\$”.


24 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.


Posted by
Alex M
20 November 2008 @ 1pm

You are the man! Thank you so much!

It’s interesting how something so little as using a $ sign in a password can cause so much havoc. I had been debugging a Data Warehouse client (DAC) application for 3 days. It was failing at the beginning of a preETL phase with a cryptic error of:

com.siebel.etl.engine.bore.NewDispatcher.run(Unknown Source)
java.lang.Thread.run(Thread.java:534)
19 SEVERE Tue Nov 18 15:26:14 CST 2008 MESSAGE:::Illegal group reference
EXCEPTION CLASS::: java.lang.IllegalArgumentException
java.util.regex.Matcher.appendReplacement(Matcher.java:561)
java.util.regex.Matcher.replaceAll(Matcher.java:661)
java.lang.String.replaceAll(String.java:1663)
com.siebel.etl.engine.core.AttachToInformaticaProcess.getCommand(Unknown Source)

After looking at your posting, I noticed the $$ at the end of the informatica server admin password that was saved in the DAC to communicate with informatica.

You saved my arse with your posting… THANK YOU SO MUCH!


Posted by
hmilligan
2 December 2008 @ 11pm

You rock. Saved me heaps of time!


Posted by
Lennarth Anaya
10 December 2008 @ 9am

Great. Thanks a lot.

My problem was exactly the dollar sign. I solved it by replacing dollar signs:

replace = replace.replaceAll(”\\$”,”\\\\\\$”);

(provided by a reader at http://www.bennadel.com/blog/255-Issues-with-Dollar-Signs-And-Java-s-Matcher-AppendReplacement-Method.htm)


Posted by
Laccitm
11 December 2008 @ 12pm

I failed my exam because I didn’t know this. :(

Next time…


Posted by
Raj
17 December 2008 @ 9pm

Its useful… How can i change (YEAR/MM/DATE) format to (DD/MMM/YEAR)???


Posted by
Nagesh
12 May 2009 @ 11am

You have no idea how much time you saved!!
Thank you so much!!
Really appreciate you thought to share this with us.


Leave a Comment

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