2010-10-15 5 views
23

Estoy usando un while(matcher.find()) para recorrer todas las coincidencias de un Patrón. Para cada instancia o coincidencia de ese patrón, encuentra, deseo reemplazar matcher.group(3) con texto nuevo. Este texto será diferente para cada uno, así que estoy usando matcher.appendReplacement() para reconstruir la cadena original con los nuevos cambios a medida que avanza. Sin embargo, appendReplacement() reemplaza todo el Patrón en lugar de solo el grupo.Cómo agregar Reemplazo en un grupo de Matcher en lugar de todo el patrón?

¿Cómo puedo hacer esto pero solo modificar el tercer grupo de la coincidencia en lugar de todo el Patrón?

Aquí es un código de ejemplo:

Pattern pattern = Pattern.compile("THE (REGEX) (EXPRESSION) (WITH MULTIPLE) GROUPS"); 
Matcher matcher = pattern.matcher("THE TEXT TO SEARCH AND MODIFY"); 
StringBuffer buffer = new StringBuffer(); 

while(matcher.find()){ 
    matcher.appendReplacement(buffer, processTheGroup(matcher.group(3)); 
} 

pero me gustaría hacer algo como esto (obviamente esto no funciona).

... 
while(matcher.find()){ 
    matcher.group(3).appendReplacement(buffer, processTheGroup(matcher.group(3)); 
} 

Algo así, donde solo reemplaza a un cierto grupo, no a todo el Patrón.

EDITAR: cambió el ejemplo de expresión regular para mostrar que no todo el patrón está agrupado.

Respuesta

16

Digamos que su patrón completo coincide con "(prefix)(infix)(suffix)", capturando las 3 partes en los grupos 1, 2 y 3, respectivamente. Ahora digamos que desea reemplazar solo el grupo 2 (el infijo), dejando el prefijo y el sufijo intactos tal como estaban.

Entonces lo que hacemos es anexar lo group(1) emparejados (sin cambios), el nuevo reemplazo para group(2), y lo que group(3) emparejado (inalterada), por lo menos así:

matcher.appendReplacement(
    buffer, 
    matcher.group(1) + processTheGroup(matcher.group(2)) + matcher.group(3) 
); 

Esto todavía se busque y sustituya todo el patrón, pero como los grupos 1 y 3 no se tocan, efectivamente solo se reemplaza el infijo.

Debe ser capaz de adaptar la misma técnica básica para su situación particular.

+0

Esto es genial gracias. ¿Hay alguna manera de hacerlo si hay algunos aspectos del Patrón que no están en grupos? (Edité el ejemplo de mi publicación original) – cottonBallPaws

+1

Si debe incluir esas partes en la coincidencia (es decir, no puede dejarlas fuera del patrón), entonces desea capturarlas en un grupo para que pueda recordar lo que coincidieron y vuelva a colocarlos sin modificaciones como parte de su reemplazo. – polygenelubricants

+0

Tenga en cuenta que esto fallará si una de las cadenas coincidentes contiene un '$'. Vea la respuesta de Warrens a continuación. – Mene

27

Veo que esto ya tiene una respuesta aceptada, pero no es del todo correcto. La respuesta correcta parece ser algo como esto:

.appendReplacement("$1" + process(m.group(2)) + "$3"); 

Esto también ilustra que "$" es un carácter especial en .appendReplacement. Por lo tanto, debe tener cuidado en su función de "proceso()" para reemplazar todo "$" por "\ $". Matcher.quoteReplacement (replacementString) hará esto por usted (gracias @Med)

La respuesta aceptada previamente fallará si los grupos 1 o 3 tienen un "$". Usted terminará con "java.lang.IllegalArgumentException: referencia de grupo ilegal"

+10

Para resolver este problema '$', 'Matcher.quoteReplacement (replacementString)' hace el truco muy bien. – Med

Cuestiones relacionadas