What's the difference between java.lang.String 's replace() and replaceAll() methods,
other than the latter uses regex? For simple substitutions like, replace . with /, is there any difference?
-
1Check out this commit.jumping_monkey– jumping_monkey2023-03-17 05:46:44 +00:00Commented Mar 17, 2023 at 5:46
13 Answers
- In
java.lang.String, thereplacemethod either takes a pair of char's or a pair ofCharSequence's (which String is implementing, so it'll happily take a pair of String's). Thereplacemethod will replace all occurrences of a char orCharSequence. - On the other hand, the first
Stringarguments ofreplaceFirstandreplaceAllare regular expressions (regex).
Using the wrong function can lead to subtle bugs.
Relevant sections from java.lang.String:
String replace(char oldChar, char newChar)
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.String replace(CharSequence target, CharSequence replacement)
Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence.String replaceAll(String regex, String replacement)
Replaces each substring of this string that matches the given regular expression with the given replacement.String replaceFirst(String regex, String replacement)
Replaces the first substring of this string that matches the given regular expression with the given replacement.
5 Comments
str.replaceAll(regex, repl) is same as Pattern.compile(regex).matcher(str).replaceAll(repl). So there is a big overhead depending on how much it's used.String#replace(target, replacement) does the same thing, except it quotes the strings: Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString())); Is there some reason why String#replace would be faster than String#replaceAll? It wouldn't seem like it since String#replace just performs additional operations.replace(CharSequence, CharSequence) was optimized. So when using more modern Java versions, there is at least some profit in using replace() over replaceAll() for literal string replacement. Although I should note that the actual extent to which it is relevant in a particular case is usually better to verify by benchmarking your code.replaceAll. The answer is more about replaceJust the regex. They both replace all :)
http://docs.oracle.com/javase/8/docs/api/java/lang/String.html
PS:
There's also a replaceFirst() (which takes a regex)
6 Comments
CharSequence is. Both replace() and replaceAll() "work with CharSequence". It's that replaceAll() considers the given CharSequence as a regular expression so it looks for regex matches, while replace() considers the given CharSequence as a plain search text so it looks for occurrences of it.replaceAll not have a name replaceRegex?Both replace() and replaceAll() replace all occurrences in the String.
Examples
I always find examples helpful to understand the differences.
replace()
Use replace() if you just want to replace some char with another char or some String with another String (actually CharSequence).
Example 1
Replace all occurrences of the character x with o.
String myString = "__x___x___x_x____xx_";
char oldChar = 'x';
char newChar = 'o';
String newString = myString.replace(oldChar, newChar);
// __o___o___o_o____oo_
Example 2
Replace all occurrences of the string fish with sheep.
String myString = "one fish, two fish, three fish";
String target = "fish";
String replacement = "sheep";
String newString = myString.replace(target, replacement);
// one sheep, two sheep, three sheep
replaceAll()
Use replaceAll() if you want to use a regular expression pattern.
Example 3
Replace any number with an x.
String myString = "__1_6____3__6_345____0";
String regex = "\\d";
String replacement = "x";
String newString = myString.replaceAll(regex, replacement);
// __x_x____x__x_xxx____x
Example 4
Remove all whitespace.
String myString = " Horse Cow\n\n \r Camel \t\t Sheep \n Goat ";
String regex = "\\s";
String replacement = "";
String newString = myString.replaceAll(regex, replacement);
// HorseCowCamelSheepGoat
See also
Documentation
replace(char oldChar, char newChar)replace(CharSequence target, CharSequence replacement)replaceAll(String regex, String replacement)replaceFirst(String regex, String replacement)
Regular Expressions
Comments
The replace() method is overloaded to accept both a primitive char and a CharSequence as arguments.
Now as far as the performance is concerned, the replace() method is a bit faster than replaceAll() because the latter first compiles the regex pattern and then matches before finally replacing whereas the former simply matches for the provided argument and replaces.
Since we know the regex pattern matching is a bit more complex and consequently slower, then preferring replace() over replaceAll() is suggested whenever possible.
For example, for simple substitutions like you mentioned, it is better to use:
replace('.', '\\');
instead of:
replaceAll("\\.", "\\\\");
Note: the above conversion method arguments are system-dependent.
3 Comments
Pattern.compile(...) content/part in their implementations, seems replace is less complex about how to define/send the first argument. It does not require "\" . Furthermore replace is available since Java 1.5 and replaceAll since 1.4- Both replace() and replaceAll() accepts two arguments and replaces all occurrences of the first substring(first argument) in a string with the second substring (second argument).
- replace() accepts a pair of char or charsequence and replaceAll() accepts a pair of regex.
It is not true that replace() works faster than replaceAll() since both uses the same code in its implementation
Pattern.compile(regex).matcher(this).replaceAll(replacement);
Now the question is when to use replace and when to use replaceAll(). When you want to replace a substring with another substring regardless of its place of occurrence in the string use replace(). But if you have some particular preference or condition like replace only those substrings at the beginning or end of a string use replaceAll(). Here are some examples to prove my point:
String str = new String("==qwerty==").replaceAll("^==", "?"); \\str: "?qwerty=="
String str = new String("==qwerty==").replaceAll("==$", "?"); \\str: "==qwerty?"
String str = new String("===qwerty==").replaceAll("(=)+", "?"); \\str: "?qwerty?"
2 Comments
replace doesn't call Pattern.compile(regex).matcher(this).replaceAll(replacement);. It calls Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));String replace(char oldChar, char newChar)
Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
String replaceAll(String regex, String replacement
Replaces each substring of this string that matches the given regular expression with the given replacement.
Comments
To throw more light with an example into how both are going to work for below code:
public static void main(String[] args)
{
String s = "My\\s aaab\\s is\\s aaab\\s name";
String s1 = s.replace("\\s", "c");
System.out.println(s1);
String s2 = s.replaceAll("\\s", "c");
System.out.println(s2);
}
Output:
Myc aaabc isc aaabc name
My\scaaab\scis\scaaab\scname
Explanation
s.replace replaces "\\s" sequence of characters with c. Hence, the output in first line. s.replaceAll considers \\s as a regex rather(equivalent to space) and replaces spaces with c. \\s in String s is escaped with first \ encountered and becomes \s.
Intellij Idea is smart enough to notify you of the usage as well. If you take a closer look at below image, you will see the difference in interpretation by Intellij idea for replace and replaceAll usage.
Comments
Old thread I know but I am sort of new to Java and discover one of it's strange things. I have used String.replaceAll() but get unpredictable results.
Something like this mess up the string:
sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");
So I designed this function to get around the weird problem:
//String.replaceAll does not work OK, that's why this function is here
public String strReplace( String s1, String s2, String s )
{
if((( s == null ) || (s.length() == 0 )) || (( s1 == null ) || (s1.length() == 0 )))
{ return s; }
while( (s != null) && (s.indexOf( s1 ) >= 0) )
{ s = s.replace( s1, s2 ); }
return s;
}
Which make you able to do:
sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );
3 Comments
String.replaceAll() expects regular expressions not literal arguments, which is why you get "unpredictable" (which are really very much predictable) results. String.replace() works the way you want.As alluded to in wickeD's answer, with replaceAll the replacement string is handled differently between replace and replaceAll. I expected a[3] and a[4] to have the same value, but they are different.
public static void main(String[] args) {
String[] a = new String[5];
a[0] = "\\";
a[1] = "X";
a[2] = a[0] + a[1];
a[3] = a[1].replaceAll("X", a[0] + "X");
a[4] = a[1].replace("X", a[0] + "X");
for (String s : a) {
System.out.println(s + "\t" + s.length());
}
}
The output of this is:
\ 1
X 1
\X 2
X 1
\X 2
This is different from perl where the replacement does not require the extra level of escaping:
#!/bin/perl
$esc = "\\";
$s = "X";
$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";
which prints \X 2
This can be quite a nuisance, as when trying to use the value returned by java.sql.DatabaseMetaData.getSearchStringEscape() with replaceAll().
Comments
From Java 9 there is some optimizations in replace method.
In Java 8 it uses a regex.
public String replace(CharSequence target, CharSequence replacement) {
return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
From Java 9 and on.
And Stringlatin implementation.
Which perform way better.
Comments
replace() method doesn't uses regex pattern whereas replaceAll() method uses regex pattern. So replace() performs faster than replaceAll().
2 Comments
To add to the already selected "Best Answer" (and others that are just as good like Suragch's), String.replace() is constrained by replacing characters that are sequential (thus taking CharSequence). However, String.replaceAll() is not constrained by replacing sequential characters only. You could replace non-sequential characters as well as long as your regular expression is constructed in such a way.
Also (most importantly and painfully obvious), replace() can only replace literal values; whereas replaceAll can replace 'like' sequences (not necessarily identical).


