Respuestas:
En java.lang.String
, el replace
método toma un par de char o un par de CharSequence
(de los cuales String es una subclase, por lo que felizmente tomará un par de String). El replace
método reemplazará todas las apariciones de un char o CharSequence
. Por otro lado, ambos String
argumentos replaceFirst
y replaceAll
son expresiones regulares (regex). Usar la función incorrecta puede provocar errores sutiles.
String#replace(target, replacement)
hace lo mismo, excepto que cita las cadenas: Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
¿Hay alguna razón por la String#replace
que sería más rápido que String#replaceAll
? No lo parecería, ya que String#replace
solo realiza operaciones adicionales.
replaceAll
? La respuesta es más sobrereplace
P: ¿Cuál es la diferencia entre los java.lang.String
métodos replace()
y replaceAll()
, aparte de eso, el último usa regex?
A: Solo la expresión regular. Ambos reemplazan a todos :)
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
PD:
También hay un replaceFirst()
(que toma una expresión regular)
CharSequence
es. Ambos replace()
y replaceAll()
"trabajar con CharSequence
". Es que replaceAll()
considera lo dado CharSequence
como una expresión regular, por lo que busca coincidencias de expresiones regulares , mientras que replace()
considera lo dado CharSequence
como un texto de búsqueda simple, por lo que busca ocurrencias de él.
Ambos replace()
y replaceAll()
reemplazar todas las ocurrencias en la cadena.
Siempre encuentro ejemplos útiles para entender las diferencias.
replace()
Úselo replace()
si solo desea reemplazar algunos char
con otros char
o algunos String
con otros String
(en realidad CharSequence
).
Ejemplo 1
Reemplace todas las ocurrencias del personaje x
con 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_
Ejemplo 2
Reemplace todas las ocurrencias de la cadena fish
con 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()
Úselo replaceAll()
si desea utilizar un patrón de expresión regular .
Ejemplo 3
Reemplace cualquier número con un 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
Ejemplo 4
Eliminar todos los espacios en blanco.
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
Documentación
replace(char oldChar, char newChar)
replace(CharSequence target, CharSequence replacement)
replaceAll(String regex, String replacement)
replaceFirst(String regex, String replacement)
Expresiones regulares
El replace()
método se sobrecarga para aceptar tanto un primitivo char
como un CharSequence
argumento.
Ahora, en lo que respecta al rendimiento, el replace()
método es un poco más rápido que replaceAll()
porque este último compila primero el patrón regex y luego coincide antes de finalmente reemplazarlo, mientras que el primero simplemente coincide con el argumento proporcionado y reemplaza.
Ya que sabemos que la coincidencia de patrones de expresiones regulares es un poco más complejo y por lo tanto más lento, a continuación, prefiriendo replace()
más replaceAll()
se sugiere siempre que sea posible.
Por ejemplo, para sustituciones simples como usted mencionó, es mejor usar:
replace('.', '\\');
en vez de:
replaceAll("\\.", "\\\\");
Nota: los argumentos del método de conversión anteriores dependen del sistema.
Pattern.compile(...)
contenido / parte en sus implementaciones, parece que replace
es menos complejo sobre cómo definir / enviar el primer argumento. No requiere "\"
. Además replace
está disponible desde Java 1.5
y replaceAll
desde1.4
String replace(char oldChar, char newChar)
Devuelve una nueva cadena resultante de reemplazar todas las apariciones de oldChar en esta cadena con newChar.
String replaceAll(String regex, String replacement
Reemplaza cada subcadena de esta cadena que coincide con la expresión regular dada con el reemplazo dado.
No es cierto que replace () funcione más rápido que replaceAll () ya que ambos usan el mismo código en su implementación
Pattern.compile (regex) .matcher (this) .replaceAll (reemplazo);
Ahora la pregunta es cuándo usar replace y cuándo usar replaceAll (). Cuando desee reemplazar una subcadena con otra subcadena independientemente de su lugar de aparición en la cadena, use replace (). Pero si tiene alguna preferencia o condición particular, como reemplazar solo esas subcadenas al principio o al final de una cadena, use replaceAll (). Aquí hay algunos ejemplos para probar mi punto:
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
no llama Pattern.compile(regex).matcher(this).replaceAll(replacement);
. LlamaPattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
Como se aludió en la respuesta de wickeD, con replaceAll la cadena de reemplazo se maneja de manera diferente entre replace y replaceAll. Esperaba que un [3] y un [4] tuvieran el mismo valor, pero son 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());
}
}
El resultado de esto es:
\ 1
X 1
\X 2
X 1
\X 2
Esto es diferente de perl donde el reemplazo no requiere el nivel adicional de escape:
#!/bin/perl
$esc = "\\";
$s = "X";
$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";
que imprime \ X 2
Esto puede ser bastante molesto, como cuando se trata de usar el valor devuelto por java.sql.DatabaseMetaData.getSearchStringEscape () con replaceAll ().
Hilo antiguo que conozco, pero soy algo nuevo en Java y descubro una de sus cosas extrañas. Lo he usado String.replaceAll()
pero obtengo resultados impredecibles.
Algo así desordena la cadena:
sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");
Así que diseñé esta función para solucionar el extraño 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;
}
Lo que te permite hacer:
sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );
String.replaceAll()
espera expresiones regulares, no argumentos literales, por lo que obtienes resultados "impredecibles" (que en realidad son muy predecibles). String.replace()
funciona de la manera que quieras.
Para agregar a la "Mejor respuesta" ya seleccionada (y otras que son tan buenas como la de Suragch), String.replace()
se limita al reemplazar los caracteres que son secuenciales (tomando así CharSequence
). Sin embargo, String.replaceAll()
no está limitado al reemplazar solo caracteres secuenciales. Puede reemplazar los caracteres no secuenciales, siempre y cuando su expresión regular se construya de esa manera.
Además (lo más importante y dolorosamente obvio), replace()
solo puede reemplazar los valores literales; mientras que replaceAll
puede reemplazar secuencias 'similares' (no necesariamente idénticas).
replace()
el método no usa el patrón regex, mientras que el replaceAll()
método usa el patrón regex. Por lo tanto, replace()
realiza más rápido que replaceAll()
.
replace funciona en el tipo de datos char pero replaceAll funciona en el tipo de datos String y ambos reemplazan todas las apariciones del primer argumento con el segundo argumento.
str.replaceAll(regex, repl)
es igual aPattern.compile(regex).matcher(str).replaceAll(repl)
. Entonces, hay una gran sobrecarga dependiendo de cuánto se use.