Genere cadenas de longitud fija llenas de espacios en blanco

95

Necesito producir una cadena de longitud fija para generar un archivo basado en la posición de los caracteres. Los caracteres que faltan deben llenarse con espacio.

Como ejemplo, el campo CIUDAD tiene una longitud fija de 15 caracteres. Para las entradas "Chicago" y "Rio de Janeiro" las salidas son

"Chicago"
" Rio de Janeiro"
.

Rafael Borja
fuente
esta es la respuesta correcta stackoverflow.com/a/38110257/2642478
Xan

Respuestas:

122

Desde Java 1.5 podemos usar el método java.lang.String.format (String, Object ...) y usar el formato printf.

La cadena de formato "%1$15s"hace el trabajo. Donde 1$indica el índice del argumento, sindica que el argumento es una Cadena y 15representa el ancho mínimo de la Cadena. Poniendo todo junto: "%1$15s".

Para un método general tenemos:

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

¿Quizás alguien pueda sugerir otra cadena de formato para llenar los espacios vacíos con un carácter específico?

Rafael Borja
fuente
2
Maybe someone can suggest another format string to fill the empty spaces with an specific character?- Eche un vistazo a la respuesta que le di.
Mike
5
Según docs.oracle.com/javase/tutorial/essential/io/formatting.html , 1$representa el índice del argumento y 15el ancho
Dmitry Minkovsky
1
Esto no limitará la longitud de la cadena a 15. Si es más larga, la salida producida también será más larga que 15
misterti
1
@misterti un string.substring lo limitaría a 15 caracteres. Saludos cordiales
Rafael Borja
1
Debería haberlo mencionado, sí. Pero el objetivo de mi comentario fue advertir sobre la posibilidad de una salida más larga de la deseada, lo que podría ser un problema para los campos de longitud fija
misterti
55

Utilice String.formatel relleno con espacios y reemplácelos con el carácter deseado.

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

Impresiones 000Apple.


Actualice una versión más eficiente (ya que no depende de ella String.format), que no tiene problemas con los espacios (gracias a Rafael Borja por la pista).

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

Impresiones 00New York.

Pero se debe agregar una verificación para evitar el intento de crear una matriz de caracteres con longitud negativa.

Miguel
fuente
El código actualizado funcionará muy bien. Eso fue lo que esperaba @thanks Mike
Sudharsan Chandrasekaran
27

Este código tendrá exactamente la cantidad de caracteres indicada; lleno de espacios o truncado en el lado derecho:

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
fuente
12

También puede escribir un método simple como el siguiente

public static String padString(String str, int leng) {
        for (int i = str.length(); i <= leng; i++)
            str += " ";
        return str;
    }
Yashpal Singla
fuente
8
Definitivamente, esta no es la respuesta más eficaz. Dado que las cadenas son inmutables en Java, esencialmente está generando N nuevas cadenas en la memoria con una longitud igual a str.length + 1 y, por lo tanto, es un desperdicio enorme. Una solución mucho mejor solo realizaría una concatenación de cadenas independientemente de la longitud de la cadena de entrada y utilizaría StringBuilder o alguna otra forma más eficiente de concatenación de cadenas en el bucle for.
anon58192932
12

Para la almohadilla derecha necesitas String.format("%0$-15s", str)

es decir, el -letrero tendrá el pad "derecho" y ningún -letrero será el pad "izquierdo"

mira mi ejemplo aquí

http://pastebin.com/w6Z5QhnJ

la entrada debe ser una cadena y un número

entrada de ejemplo: Google 1

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

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

StringUtils.leftPad(stringToPad, maxPadLength, paddingCharacter)

Mucho mejor que guayaba imo. Nunca he visto un solo proyecto empresarial de Java que use Guava, pero Apache String Utils es increíblemente común.

anon58192932
fuente
6

Aquí hay un buen truco:

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

Aquí está el código con casos de prueba;):

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

Me gusta TDD;)

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

Gran resumen aquí

JGFMK
fuente
1

Este código funciona muy bien. Rendimiento esperado

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

Codificación feliz !!

sudharsan chandrasekaran
fuente
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
fuente
0

Esta sencilla función funciona para mí:

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

Invocación:

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