2011-02-17 5 views
5

Tengo un problema al usar Rexexp en Java. El código de ejemplo se escribe a cabo ABC_012_suffix_suffix, que estaba esperando a la salida ABC_012_suffixRegexp agrupar y reemplazar Todo con. * En Java duplica el reemplazo

Pattern rexexp = Pattern.compile("(.*)"); 
    Matcher matcher = rexexp.matcher("ABC_012"); 
    String result = matcher.replaceAll("$1_suffix"); 

    System.out.println(result); 

entiendo que replaceAll sustituye a todos los grupos emparejados, la pregunta es ¿por qué es este grupo de expresiones regulares (.*) emparejando dos veces en mi cadena ABC_012 en Java?

Respuesta

5

Probablemente .* le da "coincidencia completa" y luego reduce la coincidencia con la "coincidencia vacía" (pero aún así una coincidencia). Pruebe (.+) o (^.*$) en su lugar. Ambos funcionan como se esperaba.

Al estrella regexinfo se define de la siguiente manera:

* (estrella) - Se repite el punto anterior cero o más veces. Codicioso, por lo que se combinarán tantos elementos como sea posible antes de intentar las permutaciones con menos coincidencias del elemento anterior, hasta el punto en que el elemento anterior no coincida.

3

Si lo que desea es añadir "_suffix" a la entrada de por qué no se acaba de hacer:

String result = "ABC_012" + "_suffix"; 

?

+0

(supongo, que no era la pregunta - la pregunta desconcertante fue, ¿por qué tenemos un _suffix extra añadido al resultado) –

+0

@Andreas_D: cierto, pero da el resultado correcto sin complicar las cosas con expresiones regulares innecesarias. Solo trato de mantenerlo simple :) –

6
Pattern regexp = Pattern.compile(".*"); 
Matcher matcher = regexp.matcher("ABC_012"); 
matcher.matches(); 
System.out.println(matcher.group(0)); 
System.out.println(matcher.replaceAll("$0_suffix")); 

Lo mismo sucede aquí, la salida es:

ABC_012 
ABC_012_suffix_suffix 

La razón está escondida en el método replaceAll: se trata de find todas las subsecuencias que coinciden con el patrón:

while (matcher.find()) { 
    System.out.printf("Start: %s, End: %s%n", matcher.start(), matcher.end()); 
} 

Esto dará como resultado:

Start: 0, End: 7 
Start: 7, End: 7 

lo tanto, para nuestra primera sorpresa, el matcher encuentra dos subsecuencias, "ABC_012" y otro "". Y añade "_suffix" a dos de ellos:

"ABC_012" + "_suffix" + "" + "_suffix" 
+0

La mejor respuesta hasta el momento +1 –

+0

Un muy buen análisis. Es correcto de acuerdo con Regexp, ya que. * También coincide con "". Sin embargo, esto es muy confuso :-) – UnixShadow

Cuestiones relacionadas