Name: jl125535 Date: 01/27/2003
FULL PRODUCT VERSION :
java version "1.4.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_02-b02)
Java HotSpot(TM) Client VM (build 1.4.0_02-b02, mixed mode)
A DESCRIPTION OF THE PROBLEM :
The 1.4 API specification for the behavior of the String
class's replaceAll method is internally inconsistent. The
documentation first says that the method "Replaces each
substring of this string that matches the given regular
expression with the given replacement". It then goes on
to contradict this by saying that the behavior is
identical to:
Pattern.compile(regex).matcher(str).replaceAll(repl);
This is inconsistent because Matcher.replaceAll does not
replace matches with the given replacement; it replaces
matches with the result of the evaluation of the given
replacement, which may contain references to
subexpressions and so forth.
The current API behavior matches the latter assertion, not
the former. This has caused confusion for users in the
past. (See, for example, bugs 4626653 and 4727067.)
NOTE: This is different from bug 4684543, which requests
clarification of documentation inside the java.util.regex
package.
This can be fixed by changing the documentation to state
one or the other, and ensuring that the behavior matches.
I would very much like to see String.replaceAll specified
to replace the match with the actual second parameter (ie,
the first of the two documented behaviors), for the
following reason:
If evaluated subexpressions can be contained in the target
string, then certain characters (eg, a backslash) would
need to be escaped if they occur and are not intended to
be part of such a subexpression. For an arbitrary target
String, this is a task that is just as fundamentally
difficult as that performed by String.replaceAll in the
majority of cases, anyway. Hence, String.replaceAll
becomes practically useless unless the target String is
known at compile-time. The source String already needs to
be known at compile-time, since it's a regular
expression. String.replaceAll is now usable only in a
very small minority of cases where String replacement
needs to occur.
Hence, I'd like to see the current behavior of the
reference implementation modified to the first of the two
conflicting specified behaviors; however, it is
unquestionably necessary to modify the API specification
to only specify one behavior, whichever that may be.
This is especially misleading because the first behavior
(the one that's currently not happening) gets placed in
the method summary section of the generated API
specification.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
See bug 4684543 for an excellent example of a place where String.replaceAll is
used in a way that leads to non-portability because of this problem, when it
would appear from the documentation summary on the method that the code should
work.
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Get the StringUtil class from
http://www.yoda.arachsys.com/java/skeetutil/, and use
StringUtil.replace from there, instead of the
String.replaceAll in the core API.
(Review ID: 179876)
======================================================================
- duplicates
-
JDK-4840253 Add another overloaded replace() method to java.lang.String
-
- Closed
-
-
JDK-4948767 String.replaceAll()/replaceFirst(): alternatives without regular expressions
-
- Closed
-
- relates to
-
JDK-6325596 (spec) String.replaceFirst doc could be clearer about special characters in replacement string
-
- Closed
-