2010-11-26 6 views
7

No sé cómo explicar el problema en inglés sencillo, así que me ayudo con el ejemplo de la expresión regular. Tengo algo similar a esto (el ejemplo es más o menos simplificada):¿Hay alguna forma de capturar cada grupo si coinciden varias ocurrencias?

((\\d+) - (\\d+)\n)+ 

Este patrón coincide con estas líneas a la vez:

123 - 23 
32 - 321 
3 - 0 
99 - 55 

El patrón contiene 3 grupos: el primero coincide con una línea, el segundo corresponde al primer número en la línea, y el tercero corresponde al segundo número en la línea.

¿Existe la posibilidad de obtener todos esos números? Matcher tiene solo 3 grupos. El primero devuelve 99 - 55, el segundo - 99 y el tercero - 55.

SSCCE:

class Test { 
    private static final Pattern pattern = Pattern.compile("((\\d+) - (\\d+)\n)+"); 

    public static void parseInput(String input) { 

     Matcher matcher = pattern.matcher(input); 

     if (matcher.matches()) { 

      for (int i = 0; i <= matcher.groupCount(); i++) { 
       System.out.println("------------"); 
       System.out.println("Group " + i + ": " + matcher.group(i)); 
      } 
      System.out.println(); 
     } 

    } 

    public static void main(String[] args) { 
     parseInput("123 - 23\n32 - 321\n3 - 0\n99 - 55\n"); 
    } 
} 

Respuesta

5

Si estoy no equivocada (una posibilidad), entonces cada vez que llame matcher.matches(), se actualiza con el siguiente partido. Así que, básicamente, cambie el if (matcher.matches()) en un while (matcher.find()), y ya está listo.

EDIT: En realidad, no es matches, es find que hace esto:

http://download.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#find%28%29

He aquí un ejemplo de su uso:

http://download.oracle.com/javase/tutorial/essential/regex/test_harness.html

+0

¿Es correcto?matches() o matcher.find() que se volverán a hacer cada vez que lo llame? (o ambas) –

+0

Ayer respondí una pregunta sobre "coincidencias", y recuerdo haberla leído, así que estoy bastante seguro de eso. 'encontrar', no sé, por desgracia. –

+0

No puedo hacerlo funcionar. ¿Tiene algún código que haya tenido éxito con esta tarea? – Roman

2

usted está tratando de coincidir con cada uno línea por separado?

Retire el + para que coincida con una sola línea y cambiar:

if (matcher.matches()) { 

a:

while (matcher.matches()) { 

y se hará en bucle una vez para cada partido y automáticamente saltar cualquier texto sin igual entre los partidos.

Tenga en cuenta que matcher.group (0) devuelve la coincidencia completa. Los grupos reales comienzan con 1.

7

Una observación más sobre la respuesta de Mike Caron: el programa no funcionará si simplemente reemplaza "si" con "mientras" y usa "buscar" en lugar de "emparejar". También debe cambiar la expresión regular: el último grupo con el signo "+" debe eliminarse, porque desea buscar múltiples ocurrencias de este patrón, y no para una ocurrencia de un grupo (..) +.

Para mayor claridad, este es el programa final que funciona:

class Test { 
    private static final Pattern pattern = Pattern.compile("(\\d+) - (\\d+)\n"); 

    public static void parseInput(String input) { 

     Matcher matcher = pattern.matcher(input); 

     while (matcher.find()) { 

      for (int i = 0; i <= matcher.groupCount(); i++) { 
       System.out.println("------------"); 
       System.out.println("Group " + i + ": " + matcher.group(i)); 
      } 
      System.out.println(); 
     } 
    } 

    public static void main(String[] args) { 
     parseInput("123 - 23\n32 - 321\n3 - 0\n99 - 55\n"); 
    } 
} 

que le dará tres grupos para cada línea, en el que el primer grupo es toda la línea y los dos grupos siguientes contienen cada uno un número. Este es un buen tutorial que me ayudó a entenderlo mejor: http://tutorials.jenkov.com/java-regex/matcher.html

Cuestiones relacionadas