Wygeneruj ciągi o stałej długości wypełnione spacjami

99

Aby wygenerować plik oparty na pozycji znaku, muszę utworzyć ciąg o stałej długości. Brakujące znaki należy wypełnić spacją.

Na przykład pole CITY ma stałą długość 15 znaków. W przypadku wejść „Chicago” i „Rio de Janeiro” dane wyjściowe to

„Chicago”
„Rio de Janeiro”
.

Rafael Borja
źródło
to jest poprawna odpowiedź stackoverflow.com/a/38110257/2642478
Xan

Odpowiedzi:

129

Od Javy 1.5 możemy używać metody java.lang.String.format (String, Object ...) i używać formatu podobnego do printf.

Ciąg formatu "%1$15s"wykonuje zadanie. Gdzie 1$wskazuje indeks argumentu, swskazuje, że argument jest ciągiem i 15reprezentuje minimalną szerokość ciągu. Wprowadzenie go wszyscy razem: "%1$15s".

Dla ogólnej metody mamy:

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

Może ktoś może zasugerować inny ciąg formatujący, aby wypełnić puste przestrzenie określonym znakiem?

Rafael Borja
źródło
2
Maybe someone can suggest another format string to fill the empty spaces with an specific character?- spójrz na odpowiedź, której udzieliłem.
Mike
5
Według docs.oracle.com/javase/tutorial/essential/io/formatting.html , 1$reprezentuje indeks argumentów i 15szerokość
Dmitry Minkovsky
1
Nie ograniczy to ciągu do długości 15. Jeśli jest dłuższy, wyprodukowana produkcja będzie również dłuższa niż 15
misterti
1
@misterti a string.substring ograniczyłoby go do 15 znaków. Z poważaniem
Rafael Borja
1
Powinienem o tym wspomnieć, tak. Ale celem mojego komentarza było ostrzeżenie o możliwości dłuższego wyjścia niż oczekiwano, co może być problemem dla pól o stałej długości
misterti
56

Wykorzystaj String.formatdopełnienie spacjami i zastąp je żądanymi znakami.

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

Wydruki 000Apple.


Zaktualizuj bardziej wydajną wersję (ponieważ nie polega na String.format), która nie ma problemu ze spacjami (dzięki dla Rafaela Borji za podpowiedź).

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

Wydruki 00New York.

Należy jednak dodać kontrolę, aby zapobiec próbie utworzenia tablicy znaków o ujemnej długości.

mikrofon
źródło
Zaktualizowany kod będzie działał świetnie. Tego się spodziewałem @thanks mike
sudharsan chandrasekaran
28

Ten kod będzie miał dokładnie określoną liczbę znaków; wypełnione spacjami lub obcięte po prawej stronie:

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
źródło
13

Odpowiedni pad, którego potrzebujesz String.format("%0$-15s", str)

to znaczy - znak będzie "prawy", a żaden -znak "lewy"

zobacz mój przykład tutaj

http://pastebin.com/w6Z5QhnJ

wejście musi być ciągiem i liczbą

przykładowe wejście: Google 1

Bui Dinh Ngoc
źródło
12

Możesz także napisać prostą metodę, jak poniżej

public static String padString(String str, int leng) {
        for (int i = str.length(); i <= leng; i++)
            str += " ";
        return str;
    }
Yashpal Singla
źródło
8
To zdecydowanie nie jest najlepsza odpowiedź. Ponieważ łańcuchy znaków są niezmienne w Javie, generalnie generujesz w pamięci N nowych ciągów o długości równej długości łańcucha + 1, a zatem jest to ogromnie marnotrawstwo. Znacznie lepsze rozwiązanie wykonałoby konkatenację tylko jednego ciągu znaków, niezależnie od długości ciągu wejściowego i wykorzystywałoby StringBuilder lub inny bardziej wydajny sposób łączenia ciągów w pętli for.
anon58192932
10
import org.apache.commons.lang3.StringUtils;

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

StringUtils.leftPad(stringToPad, maxPadLength, paddingCharacter)

O wiele lepiej niż imo guawa. Nigdy nie widziałem pojedynczego projektu Java dla przedsiębiorstw, który używa Guava, ale Apache String Utils jest niezwykle powszechny.

anon58192932
źródło
6

Oto fajna sztuczka:

// 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();
  }
}
OldCurmudgeon
źródło
4
String.format("%15s",s) // pads right
String.format("%-15s",s) // pads left

Świetne podsumowanie tutaj

JGFMK
źródło
3

Oto kod z przypadkami testowymi;):

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

Lubię TDD;)

Palgaz
źródło
1

Ten kod działa świetnie. Oczekiwany wynik

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

Miłego kodowania !!

sudharsan chandrasekaran
źródło
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
źródło
0

Ta prosta funkcja działa dla mnie:

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

Wezwanie:

String s = leftPad(myString, 10, "0");
WvdHooven
źródło