2012-03-28 12 views
7

Mi código:partidos de longitud cero en Java expresiones regulares

Pattern pattern = Pattern.compile("a?"); 
Matcher matcher = pattern.matcher("ababa"); 
while(matcher.find()){ 
    System.out.println(matcher.start()+"["+matcher.group()+"]"+matcher.end()); 
} 

Salida:

0[a]1 
1[]1 
2[a]3 
3[]3 
4[a]5 
5[]5 

Lo que sé:

  • "? Un" significa cero o una ocurrencia del caracter 'a'.

Java API dice:

  • matcher.start() devuelve el índice comienzo del partido anterior.
  • matcher.end() devuelve el desplazamiento después del último carácter coincidente.
  • matcher.group() devuelve la subsecuencia de entrada que coincide con la coincidencia anterior . Para un matcher m con secuencia de entrada s, las expresiones m.group() y s.substring (m.start(), m.end()) son equivalentes. Y para algunos patrones, por ejemplo, un *, coinciden con la cadena vacía. Este método devolverá la cadena vacía cuando el patrón coincida con la cadena vacía en la entrada.

lo que quiero saber:

  1. ¿En qué situaciones hace que el motor de expresiones regulares se encuentra con un cero aparición de un personaje (s) dada - Relación carácter 'a'.
  2. En esas situaciones, ¿cuáles son los valores realmente devueltos por los métodos start(), end() y group() en el emparejador? He mencionado lo que dice la API java. Pero no estoy muy claro cuando se trata de la situación práctica como se indica arriba.

Respuesta

10

El ? es un cuantificador codicioso, por lo tanto, primero intentará hacer coincidir la ocurrencia 1 antes de intentar la ocurrencia 0. En su cadena,

  1. comienza con el primer carácter "a" e intenta hacer coincidir el inicio de 1-ocurrencia. El carácter 'a' coincide y devuelve el primer resultado que ve
  2. y luego avanza y encuentra una 'b'. El carácter 'b' no coincide con su recirculación de 1 regexp, por lo que el motor retrocede e intenta hacer coincidir una 0-ocurrencia. El resultado es que la cadena vacía coincide -> obtiene su segundo resultado.
  3. luego se mueve delante de b ya que no hay más coincidencias posibles allí y comienza de nuevo con su segundo chasquido 'a'.
  4. etc ... usted consigue el punto ...

Es un poco más complicado que eso, pero que es la idea principal. Cuando la ocurrencia de 1 no puede coincidir, intentará con la ocurrencia de 0.

En cuanto a los valores de inicio, fin y grupo, serán donde comienza y termina el partido y el grupo es el que se ha emparejado, por lo que en la primera coincidencia de 0 ocurrencias de su cadena, obtiene 1, 1 y la cuerda emtpy. No estoy seguro de que esto realmente responda tu pregunta.

+0

+1 por mencionar la explicación de la conducta del cuantificador codicioso. Pero, ¿qué hay de los últimos 5 [] 5? ¿Por qué siempre agrega 0-ocurrencia al final de cada cadena? – namalfernandolk

+0

Tomemos un ejemplo más simple con la cadena "a". El motor arranca en 0 e intenta hacer coincidir 'a' -> éxito para la primera coincidencia y se mueve hacia la posición 1 -> en la posición 1, intenta una coincidencia de 1 evento -> falla porque se llega al final de la cadena. Todavía puede hacer una coincidencia de 0-ocurrencia -> éxito. Luego se mueve hacia adelante -> final de la cadena -> final de los partidos –

+0

Gracias mucho Guillaume. Pero después de la coincidencia exitosa de 'a' Por qué y cómo se mueve hacia adelante. No hay más índices; y no más personajes ¿No es así? – namalfernandolk

3

interactuando sobre algunos ejemplos sería limpiar el funcionamiento de matcher.find() a usted:

motor de expresiones regulares adquiere un carácter de la cadena (es decir Abeba) y trata de encontrar si el patrón está buscando en la cadena se ha encontrado o no . Si el patrón existe, entonces (como se menciona API):

matcher.start() devuelve el índice de inicio, matcher.end() devuelve el desplazamiento después del último carácter coincidente.

Si la coincidencia no existe. then start() y end() devuelve el mismo índice, que es para cumplir con la longitud coincidente es cero.

mirar hacia abajo siguiendo ejemplos:

 // Searching for string either "a" or "" 
     Pattern pattern = Pattern.compile("a?"); 
     Matcher matcher = pattern.matcher("abaabbbb"); 
     while(matcher.find()){ 
      System.out.println(matcher.start()+"["+matcher.group()+"]"+matcher.end()); 
     } 

Salida:

0[a]1 
    1[]1 
    2[a]3 
    3[a]4 
    4[]4 
    5[]5 
    6[]6 
    7[]7 
    8[]8 


     // Searching for string either "aa" or "a" 
     Pattern pattern = Pattern.compile("aa?"); 
    Matcher matcher = pattern.matcher("abaabbbb"); 
    while(matcher.find()){ 
     System.out.println(matcher.start()+"["+matcher.group()+"]"+matcher.end()); 
    } 

Salida:

0[a]1 
2[aa]4 
+0

+1 por la buena explicación. ¿Estás señalando que "a?" ¿Equalant (semánticamente) a la búsqueda de cadena ya sea "a" o ""? Entonces, ¿puedes explicar por qué siempre hay un personaje de longitud cero al final de la cadena fuente? Por ejemplo: para "aaaa" también da 4 [] 4 al final para el patrón "a?" ? – namalfernandolk

Cuestiones relacionadas