Gerar Strings de comprimento fixo preenchidos com espaços em branco


95

Eu preciso produzir uma string de comprimento fixo para gerar um arquivo baseado em posição de caractere. Os caracteres ausentes devem ser preenchidos com caractere de espaço.

Como exemplo, o campo CITY tem um comprimento fixo de 15 caracteres. Para as entradas "Chicago" e "Rio de Janeiro" as saídas são

"Chicago"
" Rio de Janeiro"
.


esta é a resposta correta stackoverflow.com/a/38110257/2642478
Xan

Respostas:


122

Desde Java 1.5, podemos usar o método java.lang.String.format (String, Object ...) e usar o formato semelhante ao printf.

A string de formato "%1$15s"faz o trabalho. Onde 1$indica o índice do argumento, sindica que o argumento é uma String e 15representa a largura mínima da String. Juntando tudo: "%1$15s".

Para um método geral, temos:

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

Talvez alguém possa sugerir outra string de formato para preencher os espaços vazios com um caractere específico?


2
Maybe someone can suggest another format string to fill the empty spaces with an specific character?- dê uma olhada na resposta que dei.
mike

5
De acordo com docs.oracle.com/javase/tutorial/essential/io/formatting.html , 1$representa o índice do argumento e 15a largura
Dmitry Minkovsky

1
Isso não limitará a string ao comprimento 15. Se for mais longa, a saída produzida também será maior do que 15
misterti

1
@misterti uma string.substring limitaria a 15 caracteres. Atenciosamente
Rafael Borja

1
Eu deveria ter mencionado isso, sim. Mas o objetivo do meu comentário foi alertar sobre a possibilidade de uma produção maior do que o desejado, o que poderia ser um problema para campos de comprimento fixo
misterti

55

Utilize String.formato preenchimento de com espaços e substitua-os pelo caractere desejado.

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

Impressões 000Apple.


Atualização de versão mais performant (já que não depende de String.format), que não tem problema de espaços (obrigado a Rafael Borja pela dica).

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

Impressões 00New York.

Mas uma verificação precisa ser adicionada para evitar a tentativa de criar uma matriz char com comprimento negativo.


O código atualizado funcionará muito bem. Era isso que eu esperava @thanks mike
sudharsan chandrasekaran

27

Este código terá exatamente a quantidade de caracteres fornecida; preenchido com espaços ou truncado no lado direito:

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

12

Você também pode escrever um método simples como abaixo

public static String padString(String str, int leng) {
        for (int i = str.length(); i <= leng; i++)
            str += " ";
        return str;
    }

8
Esta definitivamente não é a resposta com melhor desempenho. Como as strings são imutáveis ​​em Java, você está essencialmente gerando N novas strings na memória com comprimento igual a str.length + 1 e, portanto, é um desperdício enorme. Uma solução muito melhor seria realizar apenas uma concatenação de string, independentemente do comprimento da string de entrada, e utilizar StringBuilder ou alguma outra forma mais eficiente de conatenação de string no loop for.
anon58192932

12

Para o pad certo você precisa String.format("%0$-15s", str)

ou seja, o -sinal irá para o painel "direito" e nenhum -sinal irá para o painel "esquerdo"

veja meu exemplo aqui

http://pastebin.com/w6Z5QhnJ

a entrada deve ser uma string e um número

exemplo de entrada: Google 1


10
import org.apache.commons.lang3.StringUtils;

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

StringUtils.leftPad(stringToPad, maxPadLength, paddingCharacter)

Muito melhor do que goiaba. Nunca vi um único projeto Java corporativo que usa Guava, mas Apache String Utils é incrivelmente comum.



6

Aqui está um truque legal:

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

3

Aqui está o código com casos de teste;):

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

Eu gosto de TDD;)


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

Ótimo resumo aqui


1

Este código funciona muito bem. Saída esperada

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

Happy Coding !!


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

0

Esta função simples funciona para mim:

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

Invocação:

String s = leftPad(myString, 10, "0");
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.