Comment formater des chaînes en Java

Réponses:

140

En plus de String.format, jetez également un œil java.text.MessageFormat. Le format est moins laconique et un peu plus proche de l'exemple C # que vous avez fourni et vous pouvez également l'utiliser pour l'analyse.

Par exemple:

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 meilleur exemple tire parti des améliorations apportées aux varargs et à l'autoboxing de Java 1.5 et transforme ce qui précède en une seule ligne:

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

MessageFormatest un peu plus agréable pour faire des pluriels i18nisés avec le modificateur de choix. Pour spécifier un message qui utilise correctement la forme singulière lorsqu'une variable est 1 et plurielle sinon, vous pouvez faire quelque chose comme ceci:

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
la source
21
MessageFormat est à des fins de localisation, alors faites attention lorsque vous l'utilisez. Par exemple, le code suivant en MessageFormat.format("Number {0}", 1234));fonction des paramètres régionaux par défaut peut produire à la Number 1,234place de Number 1234.
pavel_kazlou
@ataylor: Bonjour, Désolé mais je suis un peu confus. Je veux quelque chose comme ça, je vais passer un objet de classe qui a des données et quand {0} it ll take firstname, quand {1} then lastname, comme ça. Est-ce possible comme {0,choice,0.getFirstName()}ça ou quelque chose comme ça?
user3145373 ツ
@ user3145373 ツ Je ne pense pas.
ataylor
Ok très bien, j'ai renvoyé un projet .Net comme celui que je veux, codeproject.com/Articles/42310/… , référez-vous à ce projet, je ressemble à ceci. Si vous connaissez un projet ou des packages disponibles comme celui-ci, veuillez me le dire. Merci
user3145373 ツ
233

Jetez un œil à String.format . Notez, cependant, qu'il prend des spécificateurs de format similaires à ceux de la famille de fonctions printf de C - par exemple:

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

Je retournerais "Hello world, 42". Vous pouvez trouver ce utile lors de l' apprentissage sur les spécificateurs. Andy Thomas-Cramer a eu la gentillesse de laisser ce lien dans un commentaire ci-dessous, qui semble pointer vers la spécification officielle. Les plus couramment utilisés sont:

  • % s - insère une chaîne
  • % d - insère un entier signé (décimal)
  • % f - insérer un nombre réel, notation standard

Ceci est radicalement différent de C #, qui utilise des références de position avec un spécificateur de format facultatif. Cela signifie que vous ne pouvez pas faire des choses comme:

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

... sans répéter réellement le paramètre passé à printf / format. (voir le commentaire de The Scrum Meister ci-dessous)


Si vous souhaitez simplement imprimer le résultat directement, vous pouvez trouver System.out.printf ( PrintStream.printf ) à votre goût.

Martin Törnwall
la source
2
Une autre option est java.text.MessageFormat, qui accepte les symboles de format de style {1}. Les symboles de format de String.format () peuvent être similaires aux symboles de format printf () de C - mais peuvent également différer. Voir download.oracle.com/javase/6/docs/api/java/util/… pour la syntaxe complète.
Andy Thomas
53
String.formatpeut également prendre des positions numériques: String.format("%2$s %1$s", "foo", "bar");sortirabar foo
The Scrum Meister
7

Si vous choisissez de ne pas utiliser String.format, l'autre option est l'opérateur + binaire

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

C'est l'équivalent de

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

Celui que vous utilisez est votre choix. StringBuilder est plus rapide, mais la différence de vitesse est marginale. Je préfère utiliser l' +opérateur (qui fait un StringBuilder.append(String.valueOf(X)))et le trouve plus facile à lire.

Ryan Amos
la source
5
Si vous voulez me répéter, veuillez expliquer pourquoi.
Ryan Amos
11
1) En réponse à une question sur le formatage des chaînes, vous expliquez le fonctionnement de l' +opérateur. 2) Votre explication n'est même pas exacte. +équivaut à utiliser StringBuilder, non String.concat. (Beaucoup trop d'informations à ce sujet.)
Søren Løvborg
6

J'ai écrit ma méthode simple pour cela:

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);
    }
}

vous pouvez donc l'utiliser comme:

SomeCommons.msfgFormat("Step {1} of {2}", 1 , "two");
Tomasz Modelski
la source
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 "============ ======================

Solution Java

  • Le "-" est utilisé pour le retrait à gauche

  • Le "15" fait que la longueur minimale de la chaîne est de 15

  • Le "s" (qui est quelques caractères après%) sera remplacé par notre chaîne
  • Le 0 remplit notre entier avec des 0 à gauche
  • Le 3 fait de notre entier une longueur minimale de 3
Ved Prakash
la source
1
Vous avez raison docs.oracle.com/javase/8/docs/api/java/util/…
ℛɑƒæĿᴿᴹᴿ
1

Cette solution a fonctionné pour moi. J'avais besoin de créer dynamiquement des URL pour un client REST, j'ai donc créé cette méthode, il vous suffit donc de passer la restURL comme ceci

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

et ajoutez autant de paramètres que nécessaire:

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

Il vous suffit d'appeler cette méthode comme ceci:

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

Le résultat

"/ client / 123 / utilisateur / 321 / commande"

Felipe Bejarano
la source
0

J'ai écrit cette fonction, elle fait exactement ce qu'il faut. Interpole un mot commençant par $la valeur de la variable du même nom.

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
la source