2012-02-02 25 views
10

Con referencia a continuación pregunta - String.replaceAll single backslashes with double backslashesjava, expresión regular, la necesidad de escapar barra invertida en expresiones regulares

escribí un programa de prueba, y me encontré con que el resultado se da en ambos casos, si me escape la barra invertida o no. Esto puede deberse a que - \ t es una secuencia de escape de Java String reconocida. (Pruebe y se quejaría). - \ t se toma como una pestaña literal en la expresión regular. No estoy seguro de las razones.

¿Hay alguna directiva general sobre el escape de expresiones regulares en Java. Creo que usar dos barras invertidas es el enfoque correcto.

Me gustaría saber su opinión.

public class TestDeleteMe { 

    public static void main(String args[]) { 
    System.out.println(System.currentTimeMillis()); 

    String str1 = "a b"; //tab between a and b 

    //pattern - a and b with any number of spaces or tabs between 
    System.out.println("matches = " + str1.matches("^a[ \\t]*b$")); 
    System.out.println("matches = " + str1.matches("^a[ \t]*b$")); 
    } 
} 

Respuesta

6

La primera forma \\t se ampliará a un char pestaña por la clase de patrones.

El segundo formulario \t se ampliará a una pestaña char por Java antes de crear un patrón.

Al final, obtienes un tab de char en cualquier dirección.

+5

Esto es correcto, el * "Creo" * no es necesario. El '" \\ t "' se traduce en '" \ t "' en la cadena de Java, que se traduce en un carácter de tabulación en el motor de expresiones regulares. El '" \ t "' se traduce en un carácter de tabulación en la cadena de Java, que permanece inalterado en la expresión regular. – Tomalak

+0

Gracias. Entiendo. – RuntimeException

+0

@Tomalak Me deshice de _'creo'_ poco ... lo siento por eso ... –

9

Hay dos interpretaciones de las secuencias de escape que se producen: primero por el compilador de Java y luego por el motor de expresiones regulares. Cuando el compilador de Java ve dos barras, las reemplaza con una barra oblicua. Cuando hay t siguiendo una barra, Java lo reemplaza con una pestaña; cuando hay un t siguiendo una doble barra, Java lo deja en paz. Sin embargo, como dos barras han sido reemplazadas por una barra oblicua, el motor de expresiones regulares ve \t y lo interpreta como una pestaña.

creo que es más limpio para permitir la expresión regular interpretar \t como una pestaña (es decir, escribir "\\t" en Java), ya que le permite ver la expresión en su forma prevista durante la depuración, la explotación forestal, etc. Si convierte Pattern con \t para encadenar, verá un carácter de tabulación en el medio de su expresión regular y puede confundirlo con otros espacios en blanco. Los patrones con \\t no tienen este problema: le mostrarán un \t con una sola barra inclinada, que le indica exactamente el tipo de espacio en blanco que coinciden.

+1

Gracias. Ahora entiendo que el motor regex entiende tanto '[\ t]' (\ t after space) como '[]' (tab después del espacio) y los procesa igual. ¿Crees que estoy en lo cierto al decir esto? '[\ t]' parece más comprensible. Entonces debo usar '[\\ t]' en Java. – RuntimeException

+0

@SatishMotwani "debe" es una palabra demasiado fuerte, pero dejar que '\\ t' fluya a la expresión regular es una buena práctica. – dasblinkenlight

6

Sí, hay una guía general sobre el escape: las secuencias de escape en su fuente Java son reemplazadas por el compilador Java (o algún preprocesador eventualmente). El compilador se quejará de cualquier secuencia de escape que desconozca, p. \s. Cuando escribe un literal String para un patrón RegEx, el compilador procesará este literal como de costumbre y reemplazará todas las secuencias de escape con el carácter correspondiente. Luego, cuando se ejecuta el programa, la clase Pattern compila la cadena de entrada, es decir, evaluará las secuencias de escape en otro momento. La clase Pattern conoce \s como una clase de caracteres y, por lo tanto, podrá compilar un patrón que contenga esta clase. Sin embargo, debe escapar al \s del compilador de Java que no conoce esta secuencia de escape. Para hacerlo, se escapa de la barra invertida que da como resultado \\s.

En resumen, siempre es necesario escapar de las clases de caracteres para patrones RegEx dos veces. Si desea hacer coincidir una barra diagonal inversa, el patrón correcto es \\\\ porque el compilador de Java lo convertirá en \\, que el compilador de patrones reconocerá como el carácter de barra invertida escapada.

+0

Gracias. Entiendo. Por lo tanto, debe escribir su 'String' en Java para que el motor de Pattern obtenga lo que espera. Creo que tendré que tener mucho cuidado al escribir expresiones regulares en Java en el futuro. – RuntimeException

0

Con org.apache.commons.lang3.StringEscapeUtils.unescapeJava (...), puede escapar de la mayoría del spl común.caracteres y también los caracteres Unicode (convierte el juego de caracteres Unicode en carácter regular legible)

Cuestiones relacionadas