Foros del Web » Programación para mayores de 30 ;) » Java »

[SOLUCIONADO] Duda con expresiones regulares

Estas en el tema de Duda con expresiones regulares en el foro de Java en Foros del Web. Hola a todos, recientemente estaba haciendo un plugin para Bukkit y me ha surgido una duda (no es necesario conocer Bukkit para contestar a esta ...
  #1 (permalink)  
Antiguo 27/03/2013, 20:19
zant95
Invitado
 
Mensajes: n/a
Puntos:
Duda con expresiones regulares

Hola a todos, recientemente estaba haciendo un plugin para Bukkit y me ha surgido una duda (no es necesario conocer Bukkit para contestar a esta cuestión). Verán, actualmente tengo esta función:

Código:
  public String variables(Player player, String text) {
    Calendar calendar = Calendar.getInstance();
    return text.replace("$gamemode", player.getGameMode().name())
          .replace("$food", Integer.toString(player.getFoodLevel()))
          .replace("$health", Integer.toString(player.getHealth()))
          .replace("$exp", Integer.toString(player.getTotalExperience()))
          .replace("$world", player.getWorld().getName())
          .replace("$hand", Integer.toString(player.getItemInHand().getTypeId()))
          .replace("$amount", Integer.toString(player.getItemInHand().getAmount()))
          .replace("$mctime", Long.toString(player.getWorld().getTime()))
          .replace("$hour", Integer.toString(calendar.get(Calendar.HOUR_OF_DAY)))
          .replace("$min", Integer.toString(calendar.get(Calendar.MINUTE)))
          .replace("$sec", Integer.toString(calendar.get(Calendar.SECOND)))
          .replace("$year", Integer.toString(calendar.get(Calendar.YEAR)))
          .replace("$month", Integer.toString(calendar.get(Calendar.MONTH)+1))
          .replace("$day", Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
  }
Con esto lo que hago es reemplazar una string con variables por los valores de esas variables. La string tendría un formato como este "$hand==32". Como ven el en código obtengo el valor de "$hand" usando el parámetro "player".
Lo que necesito ahora es no usar la variable "player" como parámetro de la función, sino que quiero usar el siguiente formato "$hand(player)==32".
Imagino que la solución a esto es mediante el uso de expresiones regulares, pero ahora mismo no se me ocurre la manera más eficiente de hacerlo, así que antes de comerme la cabeza y hacer algo demasiado complejo os pregunto a vosotros de qué manera haríais esto.

Si no me he explicado correctamente decídmelo y entraré más en detalles. Saludos!
  #2 (permalink)  
Antiguo 28/03/2013, 00:14
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 20 años
Puntos: 454
Respuesta: Duda con expresiones regulares

¿Y qué quieres hacer con este formato "$hand(player)==32"?
La función replace() admite los parámetros que admite, no entiendo lo de que no quieras usar player como segundo parámtro. ¿Qué quieres poner en su lugar?

Se bueno.
__________________
Apuntes Java
Wiki de Programación
  #3 (permalink)  
Antiguo 28/03/2013, 06:58
zant95
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda con expresiones regulares

Vale, seré más detallado. He programando el siguiente comando para Bukkit:
/sudoif nombre_de_jugador $hand==3 comando_que_se_aplica_si_se_cumple_la_condición
De esta manera la variable "$hand" es reemplazada por un valor y si coincide se hace ejecuta el siguiente comando.

Lo que quiero es hacer lo siguiente:
/sudoif $hand(nombre_de_jugador)==3 comando_que_se_aplica_si_se_cumple_la_condición
Y el problema está en que no sé cómo hacer para obtener el "nombre_de_jugador" y a la vez saber que es "$hand" la variable que quiero reemplazar.

Si necesitas ver el código fuente completo puedes mirar el proyecto en GitHub.
  #4 (permalink)  
Antiguo 28/03/2013, 07:28
Avatar de chuidiang
Colaborador
 
Fecha de Ingreso: octubre-2004
Mensajes: 3.774
Antigüedad: 20 años
Puntos: 454
Respuesta: Duda con expresiones regulares

Buenas:

Sigo sin saber si lo que quieres es reemplazar "nombre_de_jugador" por algo que tienes en una variable (igual que reemplazas $hand por un valor) o si lo que quieres es meter en una variable java lo que se haya escrito en lugar de "nombre_de_jugador" (es decir, tienes $hand(Juan) y quieres obtener el Juan ese dentro de una variable String.

Imagino que es lo último ...

Tu expresión regular comenzaría siendo $hand(.*) donde .* representa cualquier secuencia de caracteres y que es lo que quieres obtener

Hay que escapar el $ y los ( ) por ser caracteres especiales en las expresiones regulares, así que quedaría \\$hand\\(.*\\)

Finalmente, como quieres recuperar el valor de .* hay que meterlo entre paréntesis para poder recogerlo luego, quedaría \\$hand\\((.*)\\)

El código java quedaría

Código java:
Ver original
  1. Pattern patron = Pattern.compile("\\$hand\\((.*)\\)");
  2. Matcher matcher = patron.matcher(tuComandoBukkit);
  3.  
  4. // Hace que Matcher busque los trozos.
  5. matcher.find();
  6.  
  7. // Aquí saldría el nombre_de_usuario
  8. System.out.println(matcher.group(1));

Si pones más grupos de paréntesis, serían group(1), group(2), etc en el orden que los hayas puesto.

Si lo que quieres es reemplazar el $hand(nombre_de_jugador) entero y sin saber el nombre del jugador, en el replace pon esto

replaceFirst("\\$hand\\(.*\\)", Integer.toString(player.getItemInHand().getTypeId( )))

debes usar replaceFirts() o replaceAll() porque admiten una expresión regular como primer parámetro.

Se bueno.
__________________
Apuntes Java
Wiki de Programación

Última edición por chuidiang; 28/03/2013 a las 07:34
  #5 (permalink)  
Antiguo 28/03/2013, 10:25
zant95
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda con expresiones regulares

Veamos, teniendo la siguiente string:
/sudoif $hand(nombre_de_jugador)==3 comando_que_se_aplica_si_se_cumple_la_condición
Nota: no tiene por qué ser $hand, sino cualquier otro como $exp. Aunque siempre siguiendo el patrón: $*(*).

Necesito separar y tener dos variables que sean "hand" y "nombre_de_jugador" para así poder reemplazar "$hand(nombre_de_jugador)" por el valor correspondiente a "Integer.toString(nombre_de_jugador.getItemInHand() .getTypeId())".

Hay que tener en cuenta que un mismo string puede contener varios "$*(*)" donde el nombre del jugador cambie e incluso la "variable principal" cambie.

Por ejemplo:
/sudoif $exp(nombre_de_jugador_1)>$exp(nombre_de_jugador_2 ) comando_que_se_aplica_si_se_cumple_la_condición
/sudoif $food(nombre_de_jugador_2)>10 comando_que_se_aplica_si_se_cumple_la_condición

Ahí es donde tengo que saber si es "$exp(*)" por ejemplo para reemplazar por "Integer.toString(*.getTotalExperience())" o si es "$food(*)" para en ese caso reemplazar por "Integer.toString(*.getFoodLevel())".

No sé si ahora me he explicado correctamente con el asunto del problema.
Saludos!

##############################################

EDITO:

He solucionado parcialmente el problema haciendo esto:
Código:
  public String variables(String string) {
    Calendar calendar = Calendar.getInstance();
    return string.replaceAll("\\$gamemode\\((.+?)\\)", Bukkit.getServer().getPlayer("$1").getGameMode().name())
            .replaceAll("\\$world\\((.+?)\\)", Bukkit.getServer().getPlayer("$1").getWorld().getName())
            .replaceAll("\\$food\\((.+?)\\)", Integer.toString(Bukkit.getServer().getPlayer("$1").getFoodLevel()))
            .replaceAll("\\$health\\((.+?)\\)", Integer.toString(Bukkit.getServer().getPlayer("$1").getHealth()))
            .replaceAll("\\$exp\\((.+?)\\)", Integer.toString(Bukkit.getServer().getPlayer("$1").getTotalExperience()))
            .replaceAll("\\$amount\\((.+?)\\)", Integer.toString(Bukkit.getServer().getPlayer("$1").getItemInHand().getTypeId()))
            .replaceAll("\\$mctime\\((.+?)\\)", Integer.toString(Bukkit.getServer().getPlayer("$1").getItemInHand().getAmount()))
            .replace("$hour", Integer.toString(calendar.get(Calendar.HOUR_OF_DAY)))
            .replace("$min", Integer.toString(calendar.get(Calendar.MINUTE)))
            .replace("$sec", Integer.toString(calendar.get(Calendar.SECOND)))
            .replace("$year", Integer.toString(calendar.get(Calendar.YEAR)))
            .replace("$month", Integer.toString(calendar.get(Calendar.MONTH)+1))
            .replace("$day", Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)));
  }
El problema es que ahora "$1" no lo reemplaza por el nombre del usuario, sino que se queda simplemente en "$1". Sin embargo si hago esto:
Código:
.replaceAll("\\$gamemode\\((.+?)\\)",  "$1")
Sí obtengo lo que necesito.

¿Alguna idea sobre cómo podría solventar esto?

Última edición por zant95; 28/03/2013 a las 12:17
  #6 (permalink)  
Antiguo 28/03/2013, 14:32
 
Fecha de Ingreso: diciembre-2011
Mensajes: 152
Antigüedad: 12 años, 10 meses
Puntos: 34
Respuesta: Duda con expresiones regulares

No puedes usar el comodín $1 fuera de la función replace|replaceAll

Prueba con esto:
Código java:
Ver original
  1. String text = "/sudoif $exp(leviathan)>$exp(luis)";
  2. String regex = "\\$(?<command>\\w+)\\((?<player>\\w+)\\)";
  3. Pattern pattern = Pattern.compile(regex);
  4. Matcher matcher = pattern.matcher(text);
  5. while (matcher.find()) {            
  6.     String command = matcher.group("command");
  7.     String player = matcher.group("player");
  8.     System.out.printf("command: %s, player: %s\n", command, player);
  9. }

Salida:

command: exp, player: leviathan
command: exp, player: luis
  #7 (permalink)  
Antiguo 29/03/2013, 08:27
zant95
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Duda con expresiones regulares

Muchísimas gracias por la aclaración. Asunto solucionado ;D

Etiquetas: expresiones, regulares, string
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 00:58.