¿Tiene Java una forma integrada de escapar del texto arbitrario para que se pueda incluir 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.Cómo escanear texto para la expresión regular en Java
Respuesta
Desde Java 1.5, yes:
Pattern.quote("$5");
Creo que lo que está buscando es \Q$5\E
. También vea Pattern.quote(s)
introducido en Java5.
Ver Pattern javadoc para más detalles.
Tengo curiosidad si hay alguna diferencia entre esto y el uso de la bandera LITERAL, ya que el javadoc dice que no hay un indicador incrustado para encender y apagar LITERAL: http: // java. sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html#LITERAL –
Tenga en cuenta que usar literalmente \ Q y \ E solo está bien si conoce su entrada. Pattern.quote (s) también manejará el caso donde su texto realmente contiene estas secuencias. –
Diferencia entre Pattern.quote
y Matcher.quoteReplacement
no estaba claro para mí antes de ver siguiente ejemplo
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Específicamente, 'Pattern.quote' reemplaza los caracteres especiales en las cadenas de búsqueda de expresiones regulares, como. | +() Etc, y' Matcher.quoteReplacement' reemplaza los caracteres especiales en las cadenas de reemplazo, como \ 1 para las referencias retrospectivas. – Steven
No estoy de acuerdo. Pattern.quote envuelve su argumento con \ Q y \ E. No escapa a los personajes especiales. –
Matcher.quoteReplacement ("4 $ &% $") produce "4 \ $ &% \ $". Se escapa de los personajes especiales. –
primer lugar, si
- utiliza replaceAll()
- usted no utiliza Matcher .quoteReplacement()
- el texto que debe sustituirse en incluye un $ 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 enchufo largas cadenas de texto en archivos .properties, luego genero sujetos y cuerpos de correo electrónico a partir de esos. De hecho, esta parece ser la forma predeterminada de hacer i18n en Spring Framework. Puse etiquetas XML, como marcadores de posición, en las cadenas y utilizo 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 ella, con la siguiente aparecer 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 ha entrado en "$ 3" en algún lugar de su entrada y replaceAll() fue en busca de 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));
resuelto 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 = "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");
}
}
No tiene que escapar espacios. Entonces puede chagne su patrón a "([^ a-zA-z0-9])". –
Pequeño error tipográfico, grandes consecuencias: "([^ a-zA-z0-9])" tampoco coincide (es decir, no escapa) [, \,],^que ciertamente desea haber escapado! El error tipográfico es la segunda 'z' que debería ser una 'Z', de lo contrario se incluye todo, desde ASCII 65 hasta ASCII 122 – Zefiro
Puede ser demasiado tarde para responder, pero también se puede utilizar Pattern.LITERAL
, que tendría en cuenta todos los caracteres especiales durante el formateo:
Pattern.compile(textToFormat, Pattern.LITERAL);
Es especialmente agradable porque puedes combinarlo con 'Pattern.CASE_INSENSITIVE' – mjjaniec
Pattern.quote ("blabla") funciona muy bien.
El Pattern.quote() funciona muy bien. Encierra la oración con los caracteres "\ Q" y "\ E", y si lo hace, escapa "\ Q" y "\ E". Sin embargo, si lo que necesita hacer una verdadera expresión regular escape (o la costumbre de escapar), puede utilizar este código:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Este método devuelve: Algunos/\ s/wText */\, **
Códigopor 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"));
- 1. Expresión regular para extraer texto entre corchetes
- 2. Expresión regular para la URL
- 3. cómo negar cualquier expresión regular en Java
- 4. Expresión regular para devolver texto entre paréntesis
- 5. ¿Expresión regular para encontrar una expresión regular?
- 6. - (guión) en la expresión regular
- 7. Expresión regular para alfanumérico
- 8. ¿Expresión regular de Java para números negativos?
- 9. java - cadena dividida usando la expresión regular
- 10. expresión regular para no espacio en blanco b/w texto
- 11. Java expresión regular operador OR
- 12. Expresión regular simple de Java
- 13. Expresión regular: cualquier texto para ser amigable con la URL
- 14. Expresión regular para el reconocimiento de citas en el texto
- 15. Expresión regular de Java Script para detectar caracteres no ascii
- 16. expresión regular para encontrar el URL en un texto
- 17. Expresión regular para Dummys
- 18. expresión regular para encontrar caracteres especiales en Java
- 19. expresión regular para DOT
- 20. Expresión regular para no vacío
- 21. ¿Cómo puedo generar texto que coincida con una expresión regular de una expresión regular?
- 22. Expresión regular para convertir marca en HTML
- 23. Generador de texto aleatorio basado en la expresión regular
- 24. expresión regular para extraer texto de una cadena RTF
- 25. Expresión regular de Java ejecutando muy lento
- 26. Expresión regular para hacer coincidir las URL en Java
- 27. ¿Hay una expresión regular para detectar una expresión regular válida?
- 28. Expresión regular en la función de índice
- 29. expresión regular para conseguir texto entre los últimos paréntesis()
- 30. Multilínea expresión regular en C#
por favor, no es que esto no escapa a la propia cadena, pero lo envuelve el uso de '\ 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 era de esperar. – Paramaeleon
@Paramaeleon ¿Por qué esperarías que foo (x) .bar() == x.bar()? – Michael
@Paramaeleon Creo que está malinterpretando el caso de uso. – vikingsteve