问题
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?
回答1:
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("\\")));
回答2:
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++;
}
来源:https://stackoverflow.com/questions/12941266/replace-and-replaceall-in-java