Respuestas:
Desde Java 1.5, sí :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
, volverá MicE
. Usted would't espera que devuelva MICE
porque no aplicó toUpperCase()
sobre ic
. En mi ejemplo, también quote()
se aplica en el .*
insertet replaceAll()
. Tienes que hacer otra cosa, tal vez .replaceAll("*","\\E.*\\Q")
funcionaría, pero eso es contradictorio.
*.wav
en el patrón de \*\.wav
expresiones regulares , y el replaceAll lo convertiría en \.*\.wav
, lo que significa que sería coincide con archivos cuyo nombre consiste en un número arbitrario de períodos seguidos de .wav
. Lo más probable replaceAll("\\*", ".*")
es que lo hubieras necesitado si se hubieran ido con la implementación más frágil que se basa en reconocer todos los caracteres de expresiones regulares activos posibles y escapar de ellos individualmente ... ¿sería eso mucho más fácil?
La diferencia entre Pattern.quote
y Matcher.quoteReplacement
no estaba clara para mí antes de ver el siguiente ejemplo
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
reemplaza caracteres especiales en cadenas de búsqueda de expresiones regulares, como. | + (), Etc., y Matcher.quoteReplacement
reemplaza caracteres especiales en cadenas de reemplazo, como \ 1 para referencias posteriores.
quoteReplacement
solo se preocupa por los dos símbolos $
y \
que, por ejemplo, se pueden usar en cadenas de reemplazo como referencias $1
o \1
. Por lo tanto, no debe usarse para escapar / citar una expresión regular.
$Group$
con T$UYO$HI
. El $
símbolo es especial tanto en el patrón como en el reemplazo:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Puede ser demasiado tarde para responder, pero también puede usarlo Pattern.LITERAL
, lo que ignoraría todos los caracteres especiales al formatear:
Pattern.compile(textToFormat, Pattern.LITERAL);
Pattern.CASE_INSENSITIVE
Creo que lo que buscas es \Q$5\E
. Ver también Pattern.quote(s)
introducido en Java5.
Ver Patrón javadoc para más detalles.
En primer lugar, si
no pondrá un 1 al final. Verá la expresión regular de búsqueda para el primer grupo coincidente y el sub ESO en. Eso es lo que significa $ 1, $ 2 o $ 3 en el texto de reemplazo: grupos coincidentes del patrón de búsqueda.
Con frecuencia conecto cadenas largas de texto en archivos .properties, luego genero asuntos y cuerpos de correo electrónico a partir de ellos. De hecho, esta parece ser la forma predeterminada de hacer i18n en Spring Framework. Pongo etiquetas XML, como marcadores de posición, en las cadenas y uso replaceAll () para reemplazar las etiquetas XML con los valores en tiempo de ejecución.
Me encontré con un problema en el que un usuario ingresaba una cifra de dólares y centavos, con un signo de dólar. replaceAll () se atragantó, con lo siguiente apareciendo en una pista de seguimiento:
java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)
En este caso, el usuario había ingresado "$ 3" en algún lugar de su entrada y replaceAll () fue a buscar en la expresión regular de búsqueda para el tercer grupo coincidente, no encontró uno y vomitó.
Dado:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
reemplazando
msg = msg.replaceAll("<userInput \\/>", userInput);
con
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
resuelve el problema. El usuario puede ingresar cualquier tipo de caracteres, incluidos los signos de dólar, sin problema. Se comportó exactamente de la manera que cabría esperar.
Para tener un patrón protegido, puede reemplazar todos los símbolos con "\\\\", excepto dígitos y letras. Y después de eso, puede poner en ese patrón protegido sus símbolos especiales para hacer que este patrón funcione no como un texto citado estúpido, sino realmente como un patrón, sino el suyo. Sin símbolos especiales de usuario.
public class Test {
public static void main(String[] args) {
String str = "y z (111)";
String p1 = "x x (111)";
String p2 = ".* .* \\(111\\)";
p1 = escapeRE(p1);
p1 = p1.replace("x", ".*");
System.out.println( p1 + "-->" + str.matches(p1) );
//.*\ .*\ \(111\)-->true
System.out.println( p2 + "-->" + str.matches(p2) );
//.* .* \(111\)-->true
}
public static String escapeRE(String str) {
//Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
//return escaper.matcher(str).replaceAll("\\\\$1");
return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
}
}
Pattern.quote ("blabla") funciona muy bien.
Pattern.quote () funciona muy bien. Encierra la oración con los caracteres " \ Q " y " \ E ", y si se escapa "\ Q" y "\ E". Sin embargo, si necesita hacer un escape de expresión regular real (o un escape personalizado), puede usar este código:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Este método devuelve: Algunos / \ s / wText * / \, **
Código por ejemplo y pruebas:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
El símbolo ^ (Negación) se usa para hacer coincidir algo que no está en el grupo de caracteres.
Este es el enlace a las expresiones regulares
Aquí está la información de la imagen sobre la negación:
\Q
y\E
. Esto puede conducir a resultados inesperados, por ejemplo,Pattern.quote("*.wav").replaceAll("*",".*")
dará como resultado\Q.*.wav\E
y no.*\.wav
, como es de esperar.