Respostas:
Em java.lang.String
, o replace
método pega um par de caracteres ou um par de CharSequence
's (dos quais String é uma subclasse, portanto, é necessário um par de String). O replace
método substituirá todas as ocorrências de um caractere ou CharSequence
. Por outro lado, ambos os String
argumentos replaceFirst
e replaceAll
são expressões regulares (regex). Usar a função errada pode levar a erros sutis.
String#replace(target, replacement)
faz a mesma coisa, exceto que cita as strings: Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
existe alguma razão pela qual String#replace
seria mais rápido do que String#replaceAll
? Parece que não, pois String#replace
apenas realiza operações adicionais.
replaceAll
. A resposta é mais sobrereplace
P: Qual a diferença entre os java.lang.String
métodos replace()
e replaceAll()
, além disso, o último usa regex.
A: Apenas o regex. Ambos substituem todos :)
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
PS:
Há também um replaceFirst()
(que usa uma regex)
CharSequence
é. Ambos replace()
e replaceAll()
"trabalham com CharSequence
". É que replaceAll()
considera o dado CharSequence
como uma expressão regular para procurar correspondências de expressões regulares , enquanto replace()
considera o dado CharSequence
como um texto de pesquisa simples para procurar ocorrências dele.
Ambos replace()
e replaceAll()
substituem todas as ocorrências na String.
Eu sempre acho exemplos úteis para entender as diferenças.
replace()
Use replace()
se você quiser substituir alguns char
por outro char
ou outros String
por outro String
(na verdade CharSequence
).
Exemplo 1
Substitua todas as ocorrências do personagem x
por 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_
Exemplo 2
Substitua todas as ocorrências da sequência fish
por 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()
se você quiser usar um padrão de expressão regular .
Exemplo 3
Substitua qualquer número por um 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
Exemplo 4
Remova todo o espaço em branco.
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
Documentação
replace(char oldChar, char newChar)
replace(CharSequence target, CharSequence replacement)
replaceAll(String regex, String replacement)
replaceFirst(String regex, String replacement)
Expressões regulares
O replace()
método está sobrecarregado para aceitar argumentos primitivo char
e a CharSequence
as.
Agora, no que diz respeito ao desempenho, o replace()
método é um pouco mais rápido do que replaceAll()
porque o último primeiro compila o padrão regex e, em seguida, corresponde antes de finalmente substituir, enquanto o anterior simplesmente corresponde ao argumento fornecido e substitui.
Como sabemos que a correspondência do padrão regex é um pouco mais complexa e, consequentemente, mais lenta, a preferência pelo replace()
excesso replaceAll()
é sugerida sempre que possível.
Por exemplo, para substituições simples como você mencionou, é melhor usar:
replace('.', '\\');
ao invés de:
replaceAll("\\.", "\\\\");
Nota: os argumentos do método de conversão acima dependem do sistema.
Pattern.compile(...)
conteúdo / parte em suas implementações, parece replace
ser menos complexo sobre como definir / enviar o primeiro argumento. Não requer "\"
. Além disso, replace
está disponível desde Java 1.5
e replaceAll
desde1.4
String replace(char oldChar, char newChar)
Retorna uma nova string resultante da substituição de todas as ocorrências de oldChar nessa string por newChar.
String replaceAll(String regex, String replacement
Substitui cada substring dessa string que corresponde à expressão regular especificada pela substituição especificada.
Não é verdade que replace () funciona mais rápido que replaceAll (), pois ambos usam o mesmo código em sua implementação
Pattern.compile (regex) .matcher (this) .replaceAll (substituição);
Agora, a questão é quando usar replace e quando usar replaceAll (). Quando você deseja substituir uma subcadeia por outra subcadeia, independentemente de seu local de ocorrência na cadeia, use replace (). Mas se você tiver alguma preferência ou condição específica, como substituir apenas as substrings no início ou no final de uma string, use replaceAll (). Aqui estão alguns exemplos para provar meu argumento:
String str = new String("==qwerty==").replaceAll("^==", "?"); \\str: "?qwerty=="
String str = new String("==qwerty==").replaceAll("==$", "?"); \\str: "==qwerty?"
String str = new String("===qwerty==").replaceAll("(=)+", "?"); \\str: "?qwerty?"
replace
não liga Pattern.compile(regex).matcher(this).replaceAll(replacement);
. Ele chama #Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
Conforme mencionado na resposta do wickeD, com replaceAll, a cadeia de substituição é tratada de maneira diferente entre replace e replaceAll. Eu esperava que um [3] e um [4] tivessem o mesmo valor, mas eles são diferentes.
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());
}
}
A saída disso é:
\ 1
X 1
\X 2
X 1
\X 2
Isso é diferente do perl, onde a substituição não requer o nível extra de escape:
#!/bin/perl
$esc = "\\";
$s = "X";
$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";
que imprime \ X 2
Isso pode ser um incômodo, como ao tentar usar o valor retornado por java.sql.DatabaseMetaData.getSearchStringEscape () com replaceAll ().
Tópico antigo que conheço, mas sou um pouco novo em Java e descubro uma de suas coisas estranhas. Eu usei, String.replaceAll()
mas obtive resultados imprevisíveis.
Algo assim bagunça a corda:
sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");
Então, eu projetei essa função para contornar o estranho problema:
//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;
}
O que o torna capaz de fazer:
sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );
String.replaceAll()
espera expressões regulares, não argumentos literais, e é por isso que você obtém resultados "imprevisíveis" (que são realmente muito previsíveis). String.replace()
funciona da maneira que você deseja.
Para adicionar à "Melhor resposta" já selecionada (e outras que são tão boas quanto as de Suragch), a String.replace()
restrição é substituída pela substituição de caracteres que são seqüenciais (levando assim CharSequence
). No entanto, String.replaceAll()
não é restrito substituindo apenas caracteres seqüenciais. Você pode substituir caracteres não sequenciais, desde que sua expressão regular seja construída dessa maneira.
Além disso (o mais importante e dolorosamente óbvio), replace()
só pode substituir valores literais; Considerando que replaceAll
pode substituir sequências 'like' (não necessariamente idênticas).
replace()
O método não usa o padrão regex, enquanto o replaceAll()
método usa o padrão regex. Então replace()
executa mais rápido que replaceAll()
.
replace funciona no tipo de dados char, mas replaceAll funciona no tipo de dados String e ambos substituem todas as ocorrências do primeiro argumento pelo segundo argumento.
str.replaceAll(regex, repl)
é igual aPattern.compile(regex).matcher(str).replaceAll(repl)
. Portanto, existe uma grande sobrecarga, dependendo de quanto é usado.