replace() and replaceAll() in Java
Asked Answered
P

2

7

The following code uses the replace() method of the String class in Java.

String a = "abc/xyz";
System.out.println(a.replace("/", "\\"));

/ in the given String a is being replaced with \.

The same thing is wrong, if we use the replaceAll() method as follows.

System.out.println(a.replaceAll("/", "\\"));

It causes the exception java.lang.StringIndexOutOfBoundsException to be thrown. It requires two additional backslashes \ like the following, since replaceAll() uses a regex which is not the case with the replace() method.

System.out.println(a.replaceAll("/", "\\\\"));

The only question is why does this method when used with only two slashes like this a.replaceAll("/", "\\") throw java.lang.StringIndexOutOfBoundsException?


The split() method on the other hand initially issues a waring Invalid regular expression: Unexpected internal error (I'm using NetBeans 6.9.1).

String b="abc\\xyz";
System.out.println(b.split("\\")[0]+b.split("\\")[1]); //Issues a warning as specified.

An attempt to run this causes the exception java.util.regex.PatternSyntaxException to be thrown.

Since it uses a regex like replaceAll(), it requires four back slashes.

System.out.println(b.split("\\\\")[0]+b.split("\\\\")[1]);

Why does a.replaceAll("/", "\\\\"); as in the preceding case not issue such a warning or such a run time exception, even though it has an invalid pattern?

Parmer answered 17/10, 2012 at 18:52 Comment(1)
Why are you doing this? If this is for a filename, leave it be, it will work as is.Shogun
Y
11

From Javadoc String.replaceAll

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.replaceAll. Use Matcher.quoteReplacement(java.lang.String) to suppress the special meaning of these characters, if desired.

System.out.println(a.replaceAll("/", Matcher.quoteReplacement("\\")));
Yoshida answered 17/10, 2012 at 18:56 Comment(0)
B
3

Why does this method when used with only two slashes like this a.replaceAll("/", "\") throw java.lang.StringIndexOutOfBoundsException?

As you know, \ is a metacharacter in regex. When you use \ in regex, it is always followed by another character e.g. \d or \s.

Your java.lang.StringIndexOutOfBoundsException exception is coming when it tries to evaluate the pattern string ITSELF i.e. \\ and it doesn't find a following character, which is mandatory in this case. This is not coming on the argument string a --> abc/xyz as It tries to do below:

if (nextChar == '\\') {  //<-- \\ is read here
    cursor++;

    //<--Its attempting to read next character and fails
    nextChar = replacement.charAt(cursor); 
    result.append(nextChar);
    cursor++;
}
Berlioz answered 17/10, 2012 at 19:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.