regulares - pattern java
Cómo escapar texto para expresiones regulares en Java (8)
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.
¿Tiene Java una forma integrada de escapar de texto arbitrario para que se pueda incluir en una expresión regular? Por ejemplo, si mis usuarios ingresan "$ 5", me gustaría hacer coincidir eso exactamente en lugar de "5" después del final de la entrada.
Desde Java 1.5, sí :
Pattern.quote("$5");
El símbolo ^ (Negación) se usa para hacer coincidir algo que no está en el grupo de caracteres.
Información sobre la negación
En primer lugar, si
- utiliza replaceAll ()
- NO usas Matcher.quoteReplacement ()
- El texto a sustituir incluye un $ 1.
No pondrá un 1 al final. Verá la expresión regular de búsqueda para el primer grupo coincidente y el sub de ESO. Eso es lo que $ 1, $ 2 o $ 3 significa en el texto de reemplazo: grupos coincidentes del patrón de búsqueda.
Con frecuencia conecto largas cadenas 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 donde un usuario ingresa una cifra de dólares y centavos, con un signo de dólar. replaceAll () se atragantó con esto, con lo siguiente apareciendo 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 ingresó "$ 3" en algún lugar de su entrada y replaceAll () fue a buscar en el regex de búsqueda del 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 podría colocar cualquier tipo de caracteres, incluidos los signos de dólar, sin problema. Se comportó exactamente de la manera que cabría esperar.
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"));
Para tener un patrón protegido, puede reemplazar todos los símbolos con "////", excepto los dígitos y las letras. Y después de eso, puedes poner en ese patrón protegido tus símbolos especiales para hacer que este patrón funcione no como texto citado estúpido, sino como un parche, sino tuyo. 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.
El Pattern.quote () funciona muy bien. Encierra la oración con los caracteres " / Q " y " / E ", y si escapa "/ Q" y "/ E". Sin embargo, si necesita realizar 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: 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"));
Puede que sea 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);