De http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html:

\Z  The end of the input but for the final terminator, if any
\z  The end of the input

Pero, ¿qué significa en la práctica? Me puedes dar un ejemplo, cuando yo uso el \Z \z.

En mi prueba pensé que "StackOverflow\n".matches("StackOverflow\\z") devolverá true y "StackOverflow\n".matches("StackOverflow\\Z") devuelve false. Pero en realidad ambos devuelven false. ¿Dónde está el error?

6 Comentarios

  1. 34

    Aunque \Z y $ sólo partido en el final de la cadena (cuando
    la opción para el símbolo de intercalación y el dólar de partido en incrustados los saltos de línea se
    off), no es una excepción. Si la cadena termina con un salto de línea,
    luego \Z y $ coinciden en la posición antes de que el salto de línea,
    en lugar de al final de la cadena.

    Esta «mejora» fue introducido por Perl, y es copiado por muchos regex
    sabores, incluyendo Java, .NET y PCRE. En Perl, cuando la lectura de una línea
    a partir de un archivo, la cadena resultante va a terminar con un salto de línea. La lectura
    una línea de un archivo con el texto «joe» los resultados en la cadena de joe\n.
    Cuando se aplica a esta cadena, tanto ^[a-z]+$ y \A[a-z]+\Z se
    partido de «joe».

    Si usted sólo quiere un partido en el absoluto final de la cadena, utilice
    \z (en minúsculas z en lugar de la parte superior de la caja Z). \A[a-z]+\z no
    partido de joe\n. \z partidos tras el salto de línea, que no se corresponde
    por el carácter de clase.

    http://www.regular-expressions.info/anchors.html

    La forma en que lo leí este "StackOverflow\n".matches("StackOverflow\\z") debe devolver false porque su patrón no incluye la nueva línea.

    "StackOverflow\n".matches("StackOverflow\z\n") => false
    "StackOverflow\n".matches("StackOverflow\Z\n") => true
  2. 5

    La acaba. Parece que cuando Comparador.coincide con() se invoca(como en el código, detrás de las escenas), \Z se comporta como \z. Sin embargo, cuando Comparador.find() se invoca, se comportan de manera diferente a como se esperaba. El siguiente devuelve true:

    Pattern p = Pattern.compile("StackOverflow\Z");
    Matcher m = p.matcher("StackOverflow\n");
    System.out.println(m.find());

    y si reemplazar \Z con \z devuelve false.

    Esto me parece un poco sorprendente…

    • No es de extrañar (como lo he entendido a partir de la aceptación de respuesta) como \z coincide sólo con el «verdadero» final de la cadena. Y su cadena aún no ha terminado después de StackOverflow debido a la nueva línea.
  3. 1

    Yo creo que el principal problema aquí es que el comportamiento inesperado de matches(): cualquier partido debe consumir la totalidad de la cadena de entrada. Ambos ejemplos fallar debido a que las expresiones regulares no consumen el salto de línea al final de la cadena. Los anclajes no tienen nada que ver con ella.

    En la mayoría de los idiomas, un regex partido puede ocurrir en cualquier lugar, el consumo de todos, algunos o ninguno de la cadena de entrada. Y Java tiene un método, Matcher#find(), que realiza la tradicional de este tipo de partidos. Sin embargo, los resultados son todo lo contrario de lo que dijo que espera:

    Pattern.compile("StackOverflow\z").matcher("StackOverflow\n").find()  //false
    Pattern.compile("StackOverflow\Z").matcher("StackOverflow\n").find()  //true

    En el primer ejemplo, el \z debe coincidir con el final de la cadena, pero al final el carro está en el camino. En el segundo, el \Z partidos antes de que el salto de línea, que se encuentra al final de la cadena.

  4. 0

    Como Eyal, dijo, se trabaja para encontrar (), pero no para los partidos().

    Esta realidad tiene sentido. El \Z anclarse en realidad no coincida con la posición de la derecha antes de la final de la eol, terminator, pero la expresión regular como un todo no coinciden, debido a que, como un todo, es necesario para que coincida con el texto completo de ser igualada, y nada coincide con el de terminator. (El \Z coincide con la posición de la derecha antes de el terminator, que no es lo mismo).

    Si usted hizo "StackOverflow\n".matches("StackOverflow\\Z.*") usted debería estar bien.

    • \z (z minúsculas) no coincide antes de la nueva línea, que los partidos de la final, después de la nueva línea.
    • Estás en lo correcto. Me refería a \Z, por supuesto – que es el que tiene un significado especial. Yo estaba confundido por la redacción de la pregunta. Fijo ahora.
    • \Z (mayúsculas) en realidad no coincida justo antes de la final de salto de línea, tal como se define por los javadocs. El perl docs (perldoc.perl.org/perlre.html) hacer aún más claro: «\Z Coincide sólo en el final de la cadena, o antes de nueva línea al final»
  5. 0

    \Z es la misma que la $, que coincide con el final de la cadena, al final de la cadena puede ser seguido por un salto de línea.

    ¿Cuál es la diferencia entre \z y \Z en una expresión regular, y cuándo y cómo puedo usarlo?
    ¿Cuál es la diferencia entre \z y \Z en una expresión regular, y cuándo y cómo puedo usarlo?

    \z coincide con el final de la cadena, no puede ser seguido por un salto de línea.

    ¿Cuál es la diferencia entre \z y \Z en una expresión regular, y cuándo y cómo puedo usarlo?
    ¿Cuál es la diferencia entre \z y \Z en una expresión regular, y cuándo y cómo puedo usarlo?

  6. 0

    Creo que Alan Moore siempre la mejor respuesta, especialmente el punto crucial que matches silencio inserta ^ y $ en su regex argumento.

    También me gustaría añadir un par de ejemplos. Y un poco más de explicación.

    \z partidos sólo al final de la cadena.

    \Z también los partidos de la final de la cadena, pero si hay un \n, que coincidirá antes.

    Tener en cuenta este programa:

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class Main {
        public static void main(String[] args) {
            Pattern p = Pattern.compile(".+\Z"); //some word before the end of the string
            String text = "one\ntwo\nthree\nfour\n";
            Matcher m = p.matcher(text);
            while (m.find()) {
                System.out.println(m.group());
            }
        }
    }

    Encontrará 1 partido, y la impresión "four".

    Cambio \Z a \z, y que no coincide con nada, porque no quiere igualar antes de la \n.

    Sin embargo, esto también va a imprimir four, porque no hay ninguna \n al final:

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class Main {
        public static void main(String[] args) {
            Pattern p = Pattern.compile(".+\z");
            String text = "one\ntwo\nthree\nfour";
            Matcher m = p.matcher(text);
            while (m.find()) {
                System.out.println(m.group());
            }
        }
    }

Dejar respuesta

Please enter your comment!
Please enter your name here