2012-03-07 26 views
6

Estoy tratando de encontrar variables de entorno en la entrada y reemplazarlas por valores.expresión regular de java Buscar y reemplazar

El patrón de la variable de entorno es ${\\.}

Pattern myPattern = Pattern.compile("(${\\.})"); 
String line ="${env1}sojods${env2}${env3}"; 

¿Cómo puedo reemplazar env1 con 1 y env2 con 2 y env3 con 3, por lo que después de esto voy a tener una nueva cadena 1sojods23?

+0

Su ejemplo sugiere el patrón debe ser '$ {[^}]}' + o similares en lugar de '$ {} \\.'. –

+0

¿El objetivo es colapsar 'envN' hasta 'N', o reemplazar 'envN' con el valor asignado a envN en las propiedades del entorno/sistema? –

Respuesta

-1

Usar grupos una vez que coincida ${env1} será su primer grupo y luego usará regex para reemplazar lo que está en cada grupo.

Pattern p = Pattern.compile("(${\\.})"); 
Matcher m = p.matcher(line); 
while (m.find()) 
    for (int j = 0; j <= m.groupCount(); j++) 
    //here you do replacement - check on the net how to do it;) 
+0

he intentado este patrón, pero da la siguiente excepción: Excepción en hilo java.util.regex.PatternSyntaxException "principal": la repetición ilegal cerca de índice 1 ($ {\.}) – user1205079

1

Con suerte, se verá este código útil:

Pattern phone = Pattern.compile("\\$\\{env([0-9]+)\\}"); 
    String line ="${env1}sojods${env2}${env3}"; 
    Matcher action = phone.matcher(line); 
    StringBuffer sb = new StringBuffer(line.length()); 
    while (action.find()) { 
     String text = action.group(1); 
     action.appendReplacement(sb, Matcher.quoteReplacement(text)); 
    } 
    action.appendTail(sb); 
    System.out.println(sb.toString()); 

la salida es la esperada: 1sojods23.

+0

¿qué tal nombre var es env_a, env_b y env_c ? – Kent

+0

Ok no hay problema, se puede cambiar el patrón del grupo. Me refiero solo a la pregunta específica del OP, pero supongo que puede cambiar el patrón en consecuencia (después de todo, no se dio una buena especificación). –

+0

especial Gracias realmente gracias por su respuesta rápida y es realmente una gran respuesta. – user1205079

2

Esto le da 1sojods23:

String s = "${env1}sojods${env2}${env3}"; 
final Pattern myPattern = Pattern.compile("\\$\\{[^\\}]*\\}"); 
Matcher m = myPattern.matcher(s); 
int i = 0; 
while (m.find()) { 
    s = m.replaceFirst(String.valueOf(++i)); 
    m = myPattern.matcher(s); 
} 

System.out.println(s); 

y esto también funciona:

final String re = "\\$\\{[^\\}]*\\}"; 
String s = "${env1}sojods${env2}${env3}"; 
int i = 0; 
String t; 
while (true) { 
    t = s.replaceFirst(re, String.valueOf(++i)); 
    if (s.equals(t)) { 
     break; 
    } else { 
     s = t; 
    } 
} 

System.out.println(s); 
30

cadenas en Java son inmutables, lo cual hace que esta un poco difícil si usted está hablando de un número arbitrario de cosas que Necesito encontrar y reemplazar.

Específicamente es necesario definir sus reemplazos en un Map, utilice un StringBuffer y la appendReplacements() y appendTail() métodos de Matcher. El resultado final se almacenará en su StringBuffer.

Map<String, String> replacements = new HashMap<String, String>() {{ 
    put("${env1}", "1"); 
    put("${env2}", "2"); 
    put("${env3}", "3"); 
}}; 

String line ="${env1}sojods${env2}${env3}"; 
String rx = "(\\$\\{[^}]+\\})"; 

StringBuffer sb = new StringBuffer(); 
Pattern p = Pattern.compile(rx); 
Matcher m = p.matcher(line); 

while (m.find()) 
{ 
    // Avoids throwing a NullPointerException in the case that you 
    // Don't have a replacement defined in the map for the match 
    String repString = replacements.get(m.group(1)); 
    if (repString != null)  
     m.appendReplacement(sb, repString); 
} 
m.appendTail(sb); 

System.out.println(sb.toString()); 

Salida:

1sojods23 
+0

algo mal en el código – jjLin

+1

Hermoso y elegante ... y pensando que tenía un código tan feo por ahí tratando de hacer lo mismo usando operaciones básicas de cadenas ... Haciendo exactamente lo mismo ... Map et all, reemplazando $ {variables } ... tiempo para un poco de limpieza mía. – YoYo

+0

Para reemplazar por ejemplo esto: "$ #, ## 0.0" a este "'$' #, ## 0.0" Usar Matcher.quoteReplacement (...) Así obtiene: if (replace! = Null) { String rp = Matcher.quoteReplacement ("\ '" + replace + "\'"); matcher.appendReplacement (sb, rp); } –

7

Sé que esto es viejo, me fui en busca de una, appendReplacement/appendTail ejemplo, cuando lo encontré; Sin embargo, la pregunta del OP no necesita esas complicadas soluciones de varias líneas que vi aquí.

En este caso exacto, cuando la cadena para sustituir en sí tiene el valor que desea reemplazar con, entonces esto podría hacerse fácilmente con replaceAll:

String line ="${env1}sojods${env2}${env3}"; 

System.out.println(line.replaceAll("\\$\\{env([0-9]+)\\}", "$1")); 

// Output => 1sojods23 

DEMO

Cuando la sustitución es aleatoria basado en algunas condiciones o lógica en cada coincidencia, puede usar appendReplacement/appendTail por ejemplo

0

Puede usar un StringBuffer en combinación con el método Matpend applaceReplacement(), pero si el patrón no coincide, no tiene sentido crear StringBuffer.

Por ejemplo, aquí hay un patrón que coincide con $ {...}. El grupo 1 es el contenido entre las llaves.

static Pattern rxTemplate = Pattern.compile("\\$\\{([^}\\s]+)\\}"); 

Y aquí está la función de muestra que utiliza ese patrón.

private static String replaceTemplateString(String text) { 
    StringBuffer sb = null; 
    Matcher m = rxTemplate.matcher(text); 
    while (m.find()) { 
     String t = m.group(1); 
     t = t.toUpperCase(); // LOOKUP YOUR REPLACEMENT HERE 

     if (sb == null) { 
      sb = new StringBuffer(text.length()); 
     } 
     m.appendReplacement(sb, t); 
    } 
    if (sb == null) { 
     return text; 
    } else { 
     m.appendTail(sb); 
     return sb.toString(); 
    } 
} 
Cuestiones relacionadas