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

39 thoughts on “java.lang.IllegalArgumentException: Illegal group reference, replaceAll and dollar signs”

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


    elifarley a t Gmail

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

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

    password = Matcher.quoteReplacement(password);

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

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

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

  5. 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)

  6. 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: Source)
    19 SEVERE Tue Nov 18 15:26:14 CST 2008 MESSAGE:::Illegal group reference
    EXCEPTION CLASS::: java.lang.IllegalArgumentException
    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!

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

  8. I was getting this error with Maven Replacer Plugin. I was looking for “(…)” since it said there was an error with my capture groups. You put me on the right track to realize the replacement of “${scmBranch}” (from the Maven BuildNumber Plugin) was being interpreted as a capture group due to the “$”. “\${scmBranch}” did the trick.


  9. freakin’ brilliant! i had no idea what was causing pig to throw an ” ERROR 2999: Unexpected internal error. Illegal group reference”.

    i typically use the group function in pig, so was wondering what in the heck was going on.

    avoiding the $ in a pig parameter substitution seems like the best solution for me, and it completely solved my issue.

    i can’t believe this issue isn’t better documented or even fixed, since your original post was MORE THAN 5 YEARS AGO! holy cow.

    thanks for that post – the gift that keeps on giving!

  10. I couldn’t get a SQL script to open because of this error message. Turns out you can’t have a $ in the name of your script. Thanks for mentioning the $ issue in the beginning of your blog. I only lost 5 minutes on this issue until I came here. Thanks again!

Leave a Reply

Your email address will not be published. Required fields are marked *