Cómo formatear cadenas en Java

Respuestas:

140

Además de String.format, también eche un vistazo java.text.MessageFormat. El formato es menos conciso y un poco más cercano al ejemplo de C # que ha proporcionado, y también puede usarlo para analizar.

Por ejemplo:

int someNumber = 42;
String someString = "foobar";
Object[] args = {new Long(someNumber), someString};
MessageFormat fmt = new MessageFormat("String is \"{1}\", number is {0}.");
System.out.println(fmt.format(args));

Un mejor ejemplo aprovecha las mejoras de varargs y autoboxing en Java 1.5 y convierte lo anterior en una línea:

MessageFormat.format("String is \"{1}\", number is {0}.", 42, "foobar");

MessageFormates un poco más agradable para hacer plurales i18nized con el modificador de elección. Para especificar un mensaje que usa correctamente la forma singular cuando una variable es 1 y plural, de lo contrario, puede hacer algo como esto:

String formatString = "there were {0} {0,choice,0#objects|1#object|1<objects}";
MessageFormat fmt = new MessageFormat(formatString);
fmt.format(new Object[] { new Long(numberOfObjects) });
ataylor
fuente
21
MessageFormat es para fines de localización, así que tenga cuidado al usarlo. Por ejemplo, el siguiente código, MessageFormat.format("Number {0}", 1234));según la configuración regional predeterminada, puede producir en Number 1,234lugar de Number 1234.
pavel_kazlou
@ataylor: Hola, lo siento pero estoy un poco confundido. Quiero algo así. Pasaré un objeto de clase que tenga datos y cuándo {0} it ll take firstname, cuándo {1} then lastname, así. ¿Es posible {0,choice,0.getFirstName()}o algo así?
user3145373 ツ
@ user3145373 ツ No lo creo.
ataylor
Bien, tengo que referir un proyecto .Net como el que quiero, codeproject.com/Articles/42310/… , referir este proyecto. Me veo así. Si conoce algún proyecto o paquete disponible como ese, por favor dígamelo. Gracias
user3145373 ツ
233

Echa un vistazo a String.format . Sin embargo, tenga en cuenta que toma especificadores de formato similares a los de la familia de funciones printf de C, por ejemplo:

String.format("Hello %s, %d", "world", 42);

Volvería "Hola mundo, 42". Usted puede encontrar este útil al aprender sobre los especificadores de formato. Andy Thomas-Cramer tuvo la amabilidad de dejar este enlace en un comentario a continuación, que parece apuntar a la especificación oficial. Los más utilizados son:

  • % s - inserta una cadena
  • % d - inserta un entero con signo (decimal)
  • % f - inserta un número real, notación estándar

Esto es radicalmente diferente de C #, que utiliza referencias posicionales con un especificador de formato opcional. Eso significa que no puedes hacer cosas como:

String.format("The {0} is repeated again: {0}", "word");

... sin repetir realmente el parámetro pasado a printf / format. (Ver el comentario de The Scrum Meister a continuación)


Si solo desea imprimir el resultado directamente, puede encontrar System.out.printf ( PrintStream.printf ) a su gusto.

Martin Törnwall
fuente
2
Otra opción es java.text.MessageFormat, que acepta los símbolos de formato de estilo {1}. Los símbolos de formato de String.format () pueden ser similares a los símbolos de formato printf () de C, pero también pueden diferir. Consulte download.oracle.com/javase/6/docs/api/java/util/… para ver la sintaxis completa.
Andy Thomas
53
String.formattambién puede tomar posiciones numéricas: String.format("%2$s %1$s", "foo", "bar");saldrábar foo
The Scrum Meister
7

Si elige no usar String.format, la otra opción es el operador + binario

String str = "Step " + a + " of " + b;

Este es el equivalente de

new StringBuilder("Step ").append(String.valueOf(1)).append(" of ").append(String.valueOf(2));

Cualquiera que uses es tu elección. StringBuilder es más rápido, pero la diferencia de velocidad es marginal. Prefiero usar el +operador (que hace un StringBuilder.append(String.valueOf(X)))y me resulta más fácil de leer.

Ryan Amos
fuente
55
Si me va a negar, explique por qué.
Ryan Amos
11
1) En respuesta a una pregunta sobre el formato de cadenas, explica cómo funciona el +operador. 2) Tu explicación ni siquiera es precisa. +es equivalente a usar StringBuilder, no String.concat. (Demasiada información sobre esto.)
Søren Løvborg
6

He escrito mi método simple para ello:

public class SomeCommons {
    /** Message Format like 'Some String {0} / {1}' with arguments */
    public static String msgFormat(String s, Object... args) {
        return new MessageFormat(s).format(args);
    }
}

para que puedas usarlo como:

SomeCommons.msfgFormat("Step {1} of {2}", 1 , "two");
Tomasz Modelski
fuente
5
public class StringFormat {

    public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            System.out.println("================================");
            for(int i=0;i<3;i++){
                String s1=sc.next();
                int x=sc.nextInt();
                System.out.println(String.format("%-15s%03d",s1,x));
            }
            System.out.println("================================");

    }
}

outpot "================================"
ved15space123 ved15space123 ved15space123 "=========== =====================

Solución Java

  • El "-" se utiliza para dejar sangría

  • El "15" hace que la longitud mínima de la cadena sea de 15

  • La "s" (que es unos pocos caracteres después de%) será sustituida por nuestra cadena
  • El 0 rellena nuestro entero con 0s a la izquierda
  • El 3 hace que nuestro entero tenga una longitud mínima de 3
Ved Prakash
fuente
1
Tienes razón docs.oracle.com/javase/8/docs/api/java/util/…
ℛɑƒæĿᴿᴹᴿ
1

Esta solución funcionó para mí. Necesitaba crear URL para un cliente REST dinámicamente, así que creé este método, por lo que solo tiene que pasar el restURL de esta manera

/customer/{0}/user/{1}/order

y agregue tantos parámetros como necesite:

public String createURL (String restURL, Object ... params) {       
    return new MessageFormat(restURL).format(params);
}

Solo tiene que llamar a este método así:

createURL("/customer/{0}/user/{1}/order", 123, 321);

La salida

"/ cliente / 123 / usuario / 321 / pedido"

Felipe Bejarano
fuente
0

Escribí esta función, hace lo correcto. Interpolar una palabra que comience con $el valor de la variable del mismo nombre.

private static String interpol1(String x){
    Field[] ffield =  Main.class.getDeclaredFields();
    String[] test = x.split(" ") ;
    for (String v : test ) {
        for ( Field n: ffield ) {
            if(v.startsWith("$") && ( n.getName().equals(v.substring(1))  )){
                try {
                    x = x.replace("$" + v.substring(1), String.valueOf( n.get(null)));
                }catch (Exception e){
                    System.out.println("");
                }
            }
        }
    }
    return x;
}
DefconT34
fuente