2009-06-03 18 views
14

estoy usando Matcher.appendReplacement() y funcionó muy bien hasta que mi cadena de reemplazo tenía un $ 2 en que:Matcher.appendReplacement con el texto literal

Tenga en cuenta que las barras invertidas (\) y el dólar signos ($) en la cadena de reemplazo puede hacer que los resultados sean diferentes que si se tratara como una cadena de reemplazo literal . Los signos de dólar se pueden tratar como referencias a subsecuencias capturadas como se describe anterior, y las barras invertidas se usan para caracteres de escape literales en la cadena de reemplazo .

¿Existe algún método de conveniencia en alguna parte que salga de todas las barras diagonales inversas \ y signos de dólar $ con una barra diagonal inversa? ¿O tengo que escribir uno yo mismo? Suena como que no es tan difícil, solo estaría bien si le dieron una> :(

edición: ya que te dan una, necesito replace(">:(", ":-)");

+0

NOTA: Esto no es un duplicado de "Cómo escanear texto para la expresión regular en Java". –

+0

Lo siento. Vi que la respuesta n. ° 2 mostraba cómo usar quoteReplacement y no me molestaba en leer todo. –

+0

Parece un duplicado de http://stackoverflow.com/questions/60160/how-to-escape-text-for-regular-expression-in-java para mí. – daveb

Respuesta

18

Uso Matcher.quoteReplacement en la cadena de reemplazo.

desgracia "facilidad de uso" en este caso entra en conflicto con la tipificación estricta [Explicación:... Un objeto de tipo estático de Java java.lang.String es cualquier secuencia inmutable de char s no te dice que el formato de los datos en bruto en En este escenario, tenemos texto que probablemente sea significativo para el usuario, texto codificado en un mini-lenguaje para replacem texto y texto codificados en un mini-lenguaje para el patrón. El sistema de tipo Java no tiene forma de distinguirlos (aunque puede hacer cosas divertidas con comprobadores de tipo basados ​​en anotaciones, a menudo para evitar vulnerabilidades de inyección de XSS o SQL/command). Para el mini-lenguaje de patrones puede hacer una forma de conversión con Pattern.compile, aunque ese es un uso específico y la mayoría de los métodos de API lo ignoran (para facilitar el uso). Se podría escribir un equivalente ReplacementText.compile. Además, podría ignorar los mini-idiomas y buscar las bibliotecas como "DSL". Pero todo esto no ayuda casual facilidad de uso]

+0

¡Oye, está bien! ¿Cómo extrañé eso del Javadoc?!?!?!? !! –

+0

Muy fácil de hacer. –

+1

"Desafortunadamente" la facilidad de uso "en este caso entra en conflicto con el tipado fuerte". ¿Cómo es eso? –

3

que tengo que trabajar con lo siguiente, pero me gusta la solución de Tom Hawtin mejor :-)

private static Pattern escapePattern = Pattern.compile("\\$|\\\\"); 
replacement = escapePattern.matcher(replacement).replaceAll("\\\\$0"); 
matcher.appendReplacement(stringbuffer, replacement); 

solución de Tom:.

matcher.appendReplacement(stringbuffer, Matcher.quoteReplacement(replacement)); 
11

Aquí hay otra opción:

matcher.appendReplacement(stringbuffer, ""); 
stringbuffer.append(replacement); 

appendReplacement() se encarga de la tarea de copia de más de el texto entre las coincidencias, luego StringBuffer#append() agrega el texto de reemplazo sans adulteraciones. Esto es especialmente útil si está generando el texto de reemplazo de forma dinámica, como en el Rewriter de Elliott Hughes.

+1

Esta es sin duda la mejor solución, no es necesario analizar ni escapar de la cadena de reemplazo. –

+0

Agradable y fácil. ¡Gracias! – vtuhtan