Cómo escapar de texto para expresiones regulares en Java

¿Tiene Java una forma integrada de escapar del texto arbitrario para que pueda incluirse en una expresión regular? Por ejemplo, si mis usuarios ingresan “$ 5”, me gustaría hacer coincidir exactamente eso en lugar de un “5” después del final de la entrada.

Desde Java 1.5, sí :

Pattern.quote("$5"); 

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")); 

Puede ser demasiado tarde para responder, pero también puede usar Pattern.LITERAL , que ignoraría todos los caracteres especiales al formatear:

 Pattern.compile(textToFormat, Pattern.LITERAL); 

Creo que lo que buscas es \Q$5\E También vea Pattern.quote(s) introducido en Java5.

Ver Pattern javadoc para más detalles.

Primero, si

  • Usas replaceAll ()
  • NO usas Matcher.quoteReplacement ()
  • el texto a ser sustituido incluye $ 1

no pondrá un 1 al final. Examinará la expresión regular de búsqueda para el primer grupo coincidente y 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.

Frecuentemente conecto largas cadenas de texto en archivos .properties, luego genero temas y cuerpos de correo electrónico a partir de ellos. De hecho, esta parece ser la forma predeterminada de hacer i18n en Spring Framework. Puse tags XML, como marcadores de posición, en las cadenas y utilizo replaceAll () para reemplazar las tags 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, mostrando lo siguiente en un stracktrace:

 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 buscando 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 "" among other tags // "userInput" is a String containing the user's input 

reemplazando

 msg = msg.replaceAll("", userInput); 

con

 msg = msg.replaceAll("", Matcher.quoteReplacement(userInput)); 

resuelve el problema. El usuario puede poner cualquier tipo de caracteres, incluidos los signos de dólar, sin problema. Se comportó exactamente de la manera esperada.

Para tener un patrón protegido, puede reemplazar todos los símbolos por “\\\\”, excepto los dígitos y las letras. Y después de eso, puede poner en ese patrón protegido sus símbolos especiales para que este patrón funcione no como un texto estúpido, sino como un patten, pero el suyo propio. Sin símbolos especiales de usuario.

 public class Test { public static void main(String[] args) { String str = "yz (111)"; String p1 = "xx (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.

El Pattern.quote () funciona bien. Encierra la oración con los caracteres ” \ Q ” y ” \ E “, y si escapa “\ Q” y “\ E”. Sin embargo, si necesita hacer un escaping de expresión regular real (o escape personalizado), puede usar este código:

 String someText = "Some/s/wText*/,**"; System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0")); 

Este método devuelve: Some / \ 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")); 

^ (Negación) símbolo se utiliza para hacer coincidir algo que no está en el grupo de caracteres.
Información sobre la negación

Expresiones regulares

    Intereting Posts