265 votes

Comment formater les chaînes de caractères en Java

Question primitive, mais comment formater des chaînes de caractères comme celle-ci :

"Étape {1} de {2}"

en substituant des variables à l'aide de Java ? En C#, c'est facile.

3 votes

0 votes

293voto

Martin Törnwall Points 2722

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

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

renverrait "Hello world, 42". Vous pouvez trouver ce utile lors de l'apprentissage des spécificateurs de format. Andy Thomas-Cramer a eu la gentillesse de nous laisser ce dans un commentaire ci-dessous, qui semble pointer vers les spécifications officielles. Les plus couramment utilisées sont :

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

C'est radicalement différent du C#, qui utilise des références positionnelles 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 voulez simplement imprimer le résultat directement, vous pouvez trouver System.out.printf ( PrintStream.printf ) à votre convenance.

171voto

ataylor Points 31154

En plus de String.format, regardez aussi 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 syntaxique.

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 exemple plus sympa tire parti des améliorations apportées aux varargs et à l'autoboxing dans Java 1.5 et transforme l'exemple ci-dessus en une ligne unique :

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

MessageFormat est 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 vaut 1 et le pluriel 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) });

33voto

Nikolas Points 11342

String#format

La façon la plus fréquente de formater une chaîne de caractères est d'utiliser cette méthode statique, qui est disponible depuis Java 5 et possède deux méthodes surchargées :

La méthode est facile à utiliser et les format est défini par des formateur .

String step1 = "one";
String step2 = "two";

// results in "Step one of two"
String string = String.format("Step %s of %s", step1, step2); 

Vous pouvez passer un Locale de respecter la langue et les spécificités régionales. Reportez-vous à cette réponse pour plus d'informations : https://stackoverflow.com/a/6431949/3764965 (crédits à Martin Törnwall ).

MessageFormat

El MessageFormat est disponible depuis la première version de Java et convient à l'internationalisation. Dans sa forme la plus simple, il existe une méthode statique pour le formatage :

Souvenez-vous de MessageFormat suit un modèle spécifique différent de String#format Pour plus de détails, consultez la JavaDoc correspondante : MessageFormat - modèles .

Il est possible d'utiliser Locale Cependant, il faut instancier l'objet de la classe et le passer au constructeur puisque la méthode statique ci-dessus utilise le constructeur par défaut avec la locale par défaut. Reportez-vous à cette réponse pour plus d'informations : https://stackoverflow.com/a/6432100/3764965 (crédits à ataylor ).

Solutions JDK non standard

Il existe de nombreuses façons de formater les chaînes de caractères en utilisant des bibliothèques externes. Elles n'apportent que peu ou pas d'avantages si les bibliothèques sont importées dans le seul but de formater les chaînes. Quelques exemples :

  • Apache Commons : StringSubstitutor et des exemples dans sa JavaDoc.
  • Les cactus : FormattedText , exemples ici .
  • Il est intéressant de noter que Guava ne prévoit pas d'ajouter des fonctions de formatage ou de modélisation : #1142 .
  • ... et d'autres implémentations personnalisées.

N'hésitez pas à en ajouter, mais je ne vois aucune raison de développer davantage cette section.

Alternative depuis Java 15

Il existe une nouvelle méthode d'instance appelée String#formatted(Object... args) à partir de Java 15.

L'implémentation interne est la même que String#format(String format, Object... args) .

Formate en utilisant cette chaîne comme chaîne de format, et les arguments fournis.

String step1 = "one";
String step2 = "two";

// results in "Step one of two"
String string = "Step %s of %s".formatted(step1, step2);     

Avantage : La différence est que la méthode n'est pas static et le modèle de formatage est une chaîne elle-même à partir de laquelle un nouveau est créé sur la base de la args . Cela permet au chaînage de construire d'abord le format lui-même.

Désavantage : Il n'y a pas de méthode surchargée avec Locale et utilise donc celui par défaut. Si vous avez besoin d'utiliser un Locale vous devez vous en tenir à String#format(Locale l, String format, Object... args) .

11voto

Ryan Amos Points 2938

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

C'est vous qui choisissez celui que vous utilisez. StringBuilder est plus rapide, mais la différence de vitesse est marginale. Je préfère utiliser le + (qui fait un StringBuilder.append(String.valueOf(X))) et le trouver plus facile à lire.

9 votes

Si vous voulez me réprimander, expliquez-moi pourquoi.

12 votes

1) En réponse à une question sur le formatage des chaînes de caractères, vous expliquez comment l'élément + l'opérateur travaille. 2) Votre explication n'est même pas exacte. + est équivalent à l'utilisation de StringBuilder pas String.concat . (Beaucoup trop d'informations à ce sujet.)

9voto

Tomasz Modelski Points 103

J'ai écrit une 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);
    }
}

donc vous pouvez l'utiliser comme :

SomeCommons.msfgFormat("Step {1} of {2}", 1 , "two");

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X