Explicación del método de reemplazo en Java

A menudo uso el método replace(CharSequence,CharSequence) en Java, pero hoy encontré algo que realmente no entiendo.

Cuando lo hago :

"|||".replace("||","| |");

Por qué da como resultado: | || y no | | |? porque el segundo | no se puede incluir en dos patrones?

Para resolver mi problema tengo que escribir "|||".replace("||","| |").replace("||","| |"); que parece un poco redundante.

¿Alguien tiene una explicación que me ayude a entender mejor el mecanismo detrás?

EDITAR

Entonces se ha dicho que es el caso particular especificado en el javadoc, pero está mal, el ejemplo es el siguiente:

 * The replacement proceeds from the beginning of the string to the end, for
 * example, replacing "aa" with "b" in the string "aaa" will result in
 * "ba" rather than "ab".

Entonces es diferente de mi caso porque el resultado "ba" ya no coincide con "aa". Mientras que en mi caso el resultado "| ||" todavía contiene el patrón.

preguntado el 03 de mayo de 12 a las 15:05

Tenga en cuenta que ese caso de uso particular se menciona explícitamente en el javadoc de ese método:

@Robin No veo que me refiero a este documento docs.oracle.com/javase/7/docs/api/java/lang/… No deberían quitar este ejemplo... -

Debe leer el documento del método de reemplazo con CharSequence (el método que menciona en su pregunta). En JDK7 todavía contiene este ejemplo:

@Robin Uy, no he prestado suficiente atención.... -

@Robin Leí el ejemplo nuevamente y definitivamente no tengo el mismo caso que el del Javadoc. El ejemplo de Javadoc trata sobre el orden; el resultado ya no contiene el patrón es su caso. -

5 Respuestas

Aquí están sucediendo dos cosas que podrían causar la confusión. Primero, replace no procesará el mismo carácter dos veces, por lo que el medio | solo se puede aplicar a un solo reemplazo. En segundo lugar, replace no procesa los caracteres de reemplazo, por lo que después del primer reemplazo tendrá | ||, pero el 2 | es parte del primer reemplazo.

Entonces, básicamente, lo que obtienes es después de un reemplazo, tienes el primero || se reemplaza y el resto es | que no coincide, por lo que la sustitución está completa.

contestado el 03 de mayo de 12 a las 15:05

¡Gracias por todas las respuestas! No estaba muy seguro de que el segundo | no se puede incluir en dos patrones. La documentación da el ejemplo pero no la razón de este comportamiento. ¡Ahora sé! - alain.janinm

El reemplazo comienza mirando la secuencia de caracteres para encontrarla en su cadena original y, una vez encontrada, dice, está bien, la coincidencia comienza en start y termina en end, reemplacemos esa parte con el reemplazo y luego sigamos buscando la siguiente coincidencia del end + 1 posición

contestado el 03 de mayo de 12 a las 15:05

Hay dos posibilidades de por qué replace() podría comportarse de la manera que usted espera que lo haga:

  1. Podría considerar coincidencias superpuestas (en su ejemplo: coincidir con los caracteres 1 y 2, y luego 2 y 3). No hace eso.

  2. Podría sustituirse recursivamente, lo que significa que las cosas que se agregaron/cambiaron como resultado de una sustitución serían elegibles para más coincidencias. Tampoco hace esto.

contestado el 03 de mayo de 12 a las 15:05

No es realmente una respuesta sobre el por qué, pero es bueno que

"|||".replace("||","| |");

no resulta en "| | |". Si ese fuera el resultado, significa que el reemplazo también se realiza en una parte de la Cadena donde ya se realizaron los reemplazos. Eso haría muy fácil escribir un ciclo infinito, por ejemplo "|".replace("|", "||" ); daría como resultado "||||||...." hasta que su cadena se vuelva tan grande que se quede sin memoria

contestado el 03 de mayo de 12 a las 16:05

+1 ¡Eso tiene sentido! De lo contrario, tendrían que realizar una verificación de patrones y lanzar una excepción si el segundo contiene el primero, en este caso. Ahora lo entiendo mejor gracias! - alain.janinm

Lo que buscas es

"|||".replace("|","| "); 

or

"|||".replace("|","| ").trim();

si no quieres el último espacio.

El por qué te dejo estudiar por ti mismo. Sugerencia: busque el reemplazo de expresiones regulares.

contestado el 03 de mayo de 12 a las 15:05

No busco una solución sino una explicación. es correcto que el documento muestre este caso, pero en realidad no hay una explicación. - alain.janinm

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.