Générer des chaînes de longueur fixe remplies d'espaces blancs

95

J'ai besoin de produire une chaîne de longueur fixe pour générer un fichier basé sur la position des caractères. Les caractères manquants doivent être remplis de caractère espace.

A titre d'exemple, le champ CITY a une longueur fixe de 15 caractères. Pour les entrées «Chicago» et «Rio de Janeiro», les sorties sont

"Chicago"
"Rio de Janeiro"
.

Rafael Borja
la source
c'est la bonne réponse stackoverflow.com/a/38110257/2642478
Xan

Réponses:

122

Depuis Java 1.5, nous pouvons utiliser la méthode java.lang.String.format (String, Object ...) et utiliser le format printf.

La chaîne de format "%1$15s"fait le travail. Où 1$indique l'index de l'argument, sindique que l'argument est une chaîne et 15représente la largeur minimale de la chaîne. Mettre tous ensemble: "%1$15s".

Pour une méthode générale, nous avons:

public static String fixedLengthString(String string, int length) {
    return String.format("%1$"+length+ "s", string);
}

Peut-être que quelqu'un peut suggérer une autre chaîne de format pour remplir les espaces vides avec un caractère spécifique?

Rafael Borja
la source
2
Maybe someone can suggest another format string to fill the empty spaces with an specific character?- jetez un œil à la réponse que j'ai donnée.
mike
5
Selon docs.oracle.com/javase/tutorial/essential/io/formatting.html , 1$représente l'index de l'argument et 15la largeur
Dmitry Minkovsky
1
Cela ne limitera pas la chaîne à la longueur 15. Si elle est plus longue, la sortie produite sera également plus longue que 15
misterti
1
@misterti une chaîne.substring la limiterait à 15 caractères. Meilleures salutations
Rafael Borja
1
J'aurais dû le mentionner, oui. Mais le but de mon commentaire était d'avertir de la possibilité d'une sortie plus longue que souhaitée, ce qui pourrait être un problème pour les champs de longueur fixe
misterti
55

Utilisez String.formatle remplissage avec des espaces et remplacez-les par le caractère souhaité.

String toPad = "Apple";
String padded = String.format("%8s", toPad).replace(' ', '0');
System.out.println(padded);

Impressions 000Apple.


Mettre à jour une version plus performante (car elle ne repose pas sur String.format), qui n'a aucun problème avec les espaces (merci à Rafael Borja pour l'indice).

int width = 10;
char fill = '0';

String toPad = "New York";
String padded = new String(new char[width - toPad.length()]).replace('\0', fill) + toPad;
System.out.println(padded);

Impressions 00New York.

Mais une vérification doit être ajoutée pour empêcher la tentative de création d'un tableau de caractères de longueur négative.

Mike
la source
Le code mis à jour fonctionnera très bien. C'est ce que j'attendais @merci mike
sudharsan chandrasekaran
27

Ce code aura exactement le nombre de caractères donné; rempli d'espaces ou tronqué sur le côté droit:

private String leftpad(String text, int length) {
    return String.format("%" + length + "." + length + "s", text);
}

private String rightpad(String text, int length) {
    return String.format("%-" + length + "." + length + "s", text);
}
Kurt Huwig
la source
12

Vous pouvez également écrire une méthode simple comme ci-dessous

public static String padString(String str, int leng) {
        for (int i = str.length(); i <= leng; i++)
            str += " ";
        return str;
    }
Yashpal Singla
la source
8
Ce n'est certainement pas la réponse la plus performante. Puisque les chaînes sont immuables en Java, vous générez essentiellement N nouvelles chaînes en mémoire avec une longueur égale à str.length + 1 et donc un gaspillage énorme. Une bien meilleure solution n'effectuerait qu'une seule concaténation de chaîne quelle que soit la longueur de la chaîne d'entrée et utiliserait StringBuilder ou un autre moyen plus efficace de conaténation de chaîne dans la boucle for.
anon58192932
12

Pour le bon pad dont vous avez besoin String.format("%0$-15s", str)

c'est-à-dire que le -signe sera pad "droit" et aucun -signe ne sera pad "gauche"

voir mon exemple ici

http://pastebin.com/w6Z5QhnJ

l'entrée doit être une chaîne et un nombre

exemple d'entrée: Google 1

Bui Dinh Ngoc
la source
10
import org.apache.commons.lang3.StringUtils;

String stringToPad = "10";
int maxPadLength = 10;
String paddingCharacter = " ";

StringUtils.leftPad(stringToPad, maxPadLength, paddingCharacter)

Bien mieux que Guava imo. Jamais vu un seul projet Java d'entreprise utilisant Guava, mais Apache String Utils est incroyablement courant.

anon58192932
la source
6

Voici une astuce intéressante:

// E.g pad("sss","00000000"); should deliver "00000sss".
public static String pad(String string, String pad) {
  /*
   * Add the pad to the left of string then take as many characters from the right 
   * that is the same length as the pad.
   * This would normally mean starting my substring at 
   * pad.length() + string.length() - pad.length() but obviously the pad.length()'s 
   * cancel.
   *
   * 00000000sss
   *    ^ ----- Cut before this character - pos = 8 + 3 - 8 = 3
   */
  return (pad + string).substring(string.length());
}

public static void main(String[] args) throws InterruptedException {
  try {
    System.out.println("Pad 'Hello' with '          ' produces: '"+pad("Hello","          ")+"'");
    // Prints: Pad 'Hello' with '          ' produces: '     Hello'
  } catch (Exception e) {
    e.printStackTrace();
  }
}
VieuxCurmudgeon
la source
3

Voici le code avec les cas de tests;):

@Test
public void testNullStringShouldReturnStringWithSpaces() throws Exception {
    String fixedString = writeAtFixedLength(null, 5);
    assertEquals(fixedString, "     ");
}

@Test
public void testEmptyStringReturnStringWithSpaces() throws Exception {
    String fixedString = writeAtFixedLength("", 5);
    assertEquals(fixedString, "     ");
}

@Test
public void testShortString_ReturnSameStringPlusSpaces() throws Exception {
    String fixedString = writeAtFixedLength("aa", 5);
    assertEquals(fixedString, "aa   ");
}

@Test
public void testLongStringShouldBeCut() throws Exception {
    String fixedString = writeAtFixedLength("aaaaaaaaaa", 5);
    assertEquals(fixedString, "aaaaa");
}


private String writeAtFixedLength(String pString, int lenght) {
    if (pString != null && !pString.isEmpty()){
        return getStringAtFixedLength(pString, lenght);
    }else{
        return completeWithWhiteSpaces("", lenght);
    }
}

private String getStringAtFixedLength(String pString, int lenght) {
    if(lenght < pString.length()){
        return pString.substring(0, lenght);
    }else{
        return completeWithWhiteSpaces(pString, lenght - pString.length());
    }
}

private String completeWithWhiteSpaces(String pString, int lenght) {
    for (int i=0; i<lenght; i++)
        pString += " ";
    return pString;
}

J'aime TDD;)

Palgaz
la source
2
String.format("%15s",s) // pads right
String.format("%-15s",s) // pads left

Grand résumé ici

JGFMK
la source
1

Ce code fonctionne très bien. Production attendue

  String ItemNameSpacing = new String(new char[10 - masterPojos.get(i).getName().length()]).replace('\0', ' ');
  printData +=  masterPojos.get(i).getName()+ "" + ItemNameSpacing + ":   " + masterPojos.get(i).getItemQty() +" "+ masterPojos.get(i).getItemMeasure() + "\n";

Bon codage !!

sudharsan chandrasekaran
la source
0
public static String padString(String word, int length) {
    String newWord = word;
    for(int count = word.length(); count < length; count++) {
        newWord = " " + newWord;
    }
    return newWord;
}
hack4greatness
la source
0

Cette fonction simple fonctionne pour moi:

public static String leftPad(String string, int length, String pad) {
      return pad.repeat(length - string.length()) + string;
    }

Invocation:

String s = leftPad(myString, 10, "0");
WvdHooven
la source