Gibt es eine einfache Möglichkeit, Strings in Java aufzufüllen?
Scheint etwas zu sein, das in einer StringUtil-ähnlichen API enthalten sein sollte, aber ich kann nichts finden, das dies tut.
Gibt es eine einfache Möglichkeit, Strings in Java aufzufüllen?
Scheint etwas zu sein, das in einer StringUtil-ähnlichen API enthalten sein sollte, aber ich kann nichts finden, das dies tut.
Antworten:
Apache StringUtils
hat mehrere Methoden: leftPad
, rightPad
, center
und repeat
.
Beachten Sie jedoch, dass - wie andere in dieser Antwort erwähnt und demonstriert haben - String.format()
und die Formatter
Klassen im JDK bessere Optionen sind. Verwenden Sie sie über den Commons-Code.
Seit Java 1.5 String.format()
kann verwendet werden, um eine bestimmte Zeichenfolge links / rechts aufzufüllen.
public static String padRight(String s, int n) {
return String.format("%-" + n + "s", s);
}
public static String padLeft(String s, int n) {
return String.format("%" + n + "s", s);
}
...
public static void main(String args[]) throws Exception {
System.out.println(padRight("Howto", 20) + "*");
System.out.println(padLeft("Howto", 20) + "*");
}
Und die Ausgabe ist:
Howto *
Howto*
1$
? @leo hat eine sehr ähnliche Antwort gegeben, die nicht verwendet wird 1$
und anscheinend den gleichen Effekt hat. Macht es einen Unterschied?
Auffüllen auf 10 Zeichen:
String.format("%10s", "foo").replace(' ', '*');
String.format("%-10s", "bar").replace(' ', '*');
String.format("%10s", "longer than 10 chars").replace(' ', '*');
Ausgabe:
*******foo
bar*******
longer*than*10*chars
Zeigen Sie '*' für Zeichen des Passworts an:
String password = "secret123";
String padded = String.format("%"+password.length()+"s", "").replace(' ', '*');
Die Ausgabe hat dieselbe Länge wie die Kennwortzeichenfolge:
secret123
*********
.replace(' ', '*')
sollte eher die Wirkung der Polsterung zeigen. Der Ausdruck zum Ausblenden von Passwörtern hat dieses Problem ohnehin nicht ... Eine bessere Antwort zum Anpassen der linken und rechten Füllzeichenfolge mithilfe der nativen Java-Funktion finden Sie in meiner anderen Antwort.
String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
String.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
In Guave ist das einfach:
Strings.padStart("string", 10, ' ');
Strings.padEnd("string", 10, ' ');
Etwas Einfaches:
Der Wert sollte eine Zeichenfolge sein. Konvertieren Sie es in einen String, wenn dies nicht der Fall ist. Wie "" + 123
oderInteger.toString(123)
// let's assume value holds the String we want to pad
String value = "123";
Die Teilzeichenfolge beginnt vom Zeichenlängen-Zeichenindex bis zur Endlänge der gepolsterten:
String padded="00000000".substring(value.length()) + value;
// now padded is "00000123"
Etwas genauer
Pad rechts:
String padded = value + ("ABCDEFGH".substring(value.length()));
// now padded is "123DEFGH"
Pad links:
String padString = "ABCDEFGH";
String padded = (padString.substring(0, padString.length() - value.length())) + value;
// now padded is "ABCDE123"
Schau es dir an org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.
Der Algorithmus ist jedoch sehr einfach (Pad bis zur Größe der Zeichen):
public String pad(String str, int size, char padChar)
{
StringBuffer padded = new StringBuffer(str);
while (padded.length() < size)
{
padded.append(padChar);
}
return padded.toString();
}
Sehen Sie neben Apache Commons auch, String.format
welche in der Lage sein sollten, sich um einfaches Auffüllen zu kümmern (z. B. mit Leerzeichen).
public static String LPad(String str, Integer length, char car) {
return (str + String.format("%" + length + "s", "").replace(" ", String.valueOf(car))).substring(0, length);
}
public static String RPad(String str, Integer length, char car) {
return (String.format("%" + length + "s", "").replace(" ", String.valueOf(car)) + str).substring(str.length(), length + str.length());
}
LPad("Hi", 10, 'R') //gives "RRRRRRRRHi"
RPad("Hi", 10, 'R') //gives "HiRRRRRRRR"
RPad("Hi", 10, ' ') //gives "Hi "
RPad("Hi", 1, ' ') //gives "H"
//etc...
str
, daher ist dies korrekt.
(length - str.length())
ist 0
? Der Formatierer gibt ein FormatFlagsConversionMismatchException
Wann aus, %0s
das die Formatzeichenfolge ist.
Ich brauchte eine Weile, um das herauszufinden. Der eigentliche Schlüssel ist das Lesen dieser Formatter-Dokumentation.
// Get your data from wherever.
final byte[] data = getData();
// Get the digest engine.
final MessageDigest md5= MessageDigest.getInstance("MD5");
// Send your data through it.
md5.update(data);
// Parse the data as a positive BigInteger.
final BigInteger digest = new BigInteger(1,md5.digest());
// Pad the digest with blanks, 32 wide.
String hex = String.format(
// See: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html
// Format: %[argument_index$][flags][width]conversion
// Conversion: 'x', 'X' integral The result is formatted as a hexadecimal integer
"%1$32x",
digest
);
// Replace the blank padding with 0s.
hex = hex.replace(" ","0");
System.out.println(hex);
Ich weiß, dass dieser Thread etwas alt ist und die ursprüngliche Frage war für eine einfache Lösung, aber wenn es wirklich schnell sein soll, sollten Sie ein char-Array verwenden.
public static String pad(String str, int size, char padChar)
{
if (str.length() < size)
{
char[] temp = new char[size];
int i = 0;
while (i < str.length())
{
temp[i] = str.charAt(i);
i++;
}
while (i < size)
{
temp[i] = padChar;
i++;
}
str = new String(temp);
}
return str;
}
Die Formatierungslösung ist nicht optimal. Durch einfaches Erstellen der Formatzeichenfolge werden zwei neue Zeichenfolgen erstellt.
Die Lösung von Apache kann verbessert werden, indem der sb mit der Zielgröße initialisiert wird, die unten ersetzt wird
StringBuffer padded = new StringBuffer(str);
mit
StringBuffer padded = new StringBuffer(pad);
padded.append(value);
würde verhindern, dass der interne Puffer des jdn wächst.
StringBuffer
nicht mehrere Threads gleichzeitig auf das StringBuilder
zugreifen können (was in diesem Fall zutrifft), sollten Sie ein (in JDK1.5 +) verwenden, um den Aufwand für die Synchronisierung zu vermeiden.
Hier ist eine andere Möglichkeit, nach rechts zu tippen:
// put the number of spaces, or any character you like, in your paddedString
String paddedString = "--------------------";
String myStringToBePadded = "I like donuts";
myStringToBePadded = myStringToBePadded + paddedString.substring(myStringToBePadded.length());
//result:
myStringToBePadded = "I like donuts-------";
Seit Java 11 kann String.repeat (int) verwendet werden, um einen bestimmten String links / rechts aufzufüllen.
System.out.println("*".repeat(5)+"apple");
System.out.println("apple"+"*".repeat(5));
Ausgabe:
*****apple
apple*****
Sie können den Overhead pro Anruf reduzieren, indem Sie die Auffülldaten beibehalten, anstatt sie jedes Mal neu zu erstellen:
public class RightPadder {
private int length;
private String padding;
public RightPadder(int length, String pad) {
this.length = length;
StringBuilder sb = new StringBuilder(pad);
while (sb.length() < length) {
sb.append(sb);
}
padding = sb.toString();
}
public String pad(String s) {
return (s.length() < length ? s + padding : s).substring(0, length);
}
}
Alternativ können Sie die Ergebnislänge zu einem Parameter für die pad(...)
Methode machen. Nehmen Sie in diesem Fall die Anpassung der ausgeblendeten Auffüllung in dieser Methode anstelle im Konstruktor vor.
(Hinweis: Für zusätzliche Gutschrift machen Sie es threadsicher! ;-)
Sie können die integrierten Methoden StringBuilder append () und insert () zum Auffüllen variabler Zeichenfolgenlängen verwenden:
AbstractStringBuilder append(CharSequence s, int start, int end) ;
Zum Beispiel:
private static final String MAX_STRING = " "; //20 spaces
Set<StringBuilder> set= new HashSet<StringBuilder>();
set.add(new StringBuilder("12345678"));
set.add(new StringBuilder("123456789"));
set.add(new StringBuilder("1234567811"));
set.add(new StringBuilder("12345678123"));
set.add(new StringBuilder("1234567812234"));
set.add(new StringBuilder("1234567812222"));
set.add(new StringBuilder("12345678122334"));
for(StringBuilder padMe: set)
padMe.append(MAX_STRING, padMe.length(), MAX_STRING.length());
Das funktioniert:
"".format("%1$-" + 9 + "s", "XXX").replaceAll(" ", "0")
Es füllt Ihren String XXX mit bis zu 9 Zeichen mit einem Leerzeichen. Danach werden alle Leerzeichen durch eine 0 ersetzt. Sie können das Leerzeichen und die 0 nach Belieben ändern ...
static
Methode aufrufen , String.format(…)
anstatt eine leere Zeichenfolge zu missbrauchen. Das Speichern von vier Zeichen im Quellcode ist den Verlust der Lesbarkeit sicherlich nicht wert.
public static String padLeft(String in, int size, char padChar) {
if (in.length() <= size) {
char[] temp = new char[size];
/* Llenado Array con el padChar*/
for(int i =0;i<size;i++){
temp[i]= padChar;
}
int posIniTemp = size-in.length();
for(int i=0;i<in.length();i++){
temp[posIniTemp]=in.charAt(i);
posIniTemp++;
}
return new String(temp);
}
return "";
}
Lassen Sie mich eine Antwort für einige Fälle hinterlassen, in denen Sie links / rechts (oder Präfix / Suffix-Zeichenfolge oder Leerzeichen) auffüllen müssen, bevor Sie mit einer anderen Zeichenfolge verketten und die Länge oder eine if-Bedingung nicht testen möchten.
Das gleiche wie bei der ausgewählten Antwort würde ich die StringUtils
von Apache Commons bevorzugen, aber auf folgende Weise:
StringUtils.defaultString(StringUtils.leftPad(myString, 1))
Erklären:
myString
: Die von mir eingegebene Zeichenfolge kann null seinStringUtils.leftPad(myString, 1)
: Wenn string null ist, würde diese Anweisung auch null zurückgebendefaultString
, um eine leere Zeichenfolge anzugeben, um zu verhindern, dass null verkettet wirdDie Antworten von @ck und @Marlon Tarak sind die einzigen, die a verwenden. Dieschar[]
ist der beste Ansatz für Anwendungen, bei denen mehrere Auffüllmethoden pro Sekunde aufgerufen werden . Sie nutzen jedoch keine Optimierungen der Array-Manipulation und werden für meinen Geschmack ein wenig überschrieben. Dies kann ohne Schleifen erfolgen .
public static String pad(String source, char fill, int length, boolean right){
if(source.length() > length) return source;
char[] out = new char[length];
if(right){
System.arraycopy(source.toCharArray(), 0, out, 0, source.length());
Arrays.fill(out, source.length(), length, fill);
}else{
int sourceOffset = length - source.length();
System.arraycopy(source.toCharArray(), 0, out, sourceOffset, source.length());
Arrays.fill(out, 0, sourceOffset, fill);
}
return new String(out);
}
Einfache Testmethode:
public static void main(String... args){
System.out.println("012345678901234567890123456789");
System.out.println(pad("cats", ' ', 30, true));
System.out.println(pad("cats", ' ', 30, false));
System.out.println(pad("cats", ' ', 20, false));
System.out.println(pad("cats", '$', 30, true));
System.out.println(pad("too long for your own good, buddy", '#', 30, true));
}
Ausgänge:
012345678901234567890123456789
cats
cats
cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too long for your own good, buddy
getChars
den String
Inhalt direkt in das out
Array kopieren lassen , anstatt ihn aufzurufen source.toCharArray()
, gefolgt von System.arraycopy
. Ich würde sogar in Betracht ziehen, die Implementierung zu vereinfachen char[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);
. Dies scheint fill
zwar mehr Arbeit zu leisten, ermöglicht es der JVM jedoch, die standardmäßige Nullfüllung zu beseitigen.
java.util.Formatter
wird links und rechts Polsterung tun. Keine Notwendigkeit für ungerade Abhängigkeiten von Drittanbietern (möchten Sie sie für etwas so Triviales hinzufügen).
[Ich habe die Details ausgelassen und diesen Beitrag zum 'Community-Wiki' gemacht, da ich ihn nicht brauche.]
Alle Zeichenfolgenoperationen müssen normalerweise sehr effizient sein - insbesondere, wenn Sie mit großen Datenmengen arbeiten. Ich wollte etwas, das schnell und flexibel ist, ähnlich dem, was Sie im Befehl plsql pad erhalten. Außerdem möchte ich keine große Bibliothek für nur eine kleine Sache einfügen. Mit diesen Überlegungen war keine dieser Lösungen zufriedenstellend. Dies sind die Lösungen, die ich gefunden habe und die die besten Benchmarking-Ergebnisse erzielt haben. Wenn jemand sie verbessern kann, fügen Sie bitte Ihren Kommentar hinzu.
public static char[] lpad(char[] pStringChar, int pTotalLength, char pPad) {
if (pStringChar.length < pTotalLength) {
char[] retChar = new char[pTotalLength];
int padIdx = pTotalLength - pStringChar.length;
Arrays.fill(retChar, 0, padIdx, pPad);
System.arraycopy(pStringChar, 0, retChar, padIdx, pStringChar.length);
return retChar;
} else {
return pStringChar;
}
}
Verwenden Sie diese Funktion.
private String leftPadding(String word, int length, char ch) {
return (length > word.length()) ? leftPadding(ch + word, length, ch) : word;
}
wie benutzt man?
leftPadding(month, 2, '0');
Ausgabe: 01 02 03 04 .. 11 12
Viele Leute haben einige sehr interessante Techniken, aber ich mag es einfach zu halten, also gehe ich so vor:
public static String padRight(String s, int n, char padding){
StringBuilder builder = new StringBuilder(s.length() + n);
builder.append(s);
for(int i = 0; i < n; i++){
builder.append(padding);
}
return builder.toString();
}
public static String padLeft(String s, int n, char padding) {
StringBuilder builder = new StringBuilder(s.length() + n);
for(int i = 0; i < n; i++){
builder.append(Character.toString(padding));
}
return builder.append(s).toString();
}
public static String pad(String s, int n, char padding){
StringBuilder pad = new StringBuilder(s.length() + n * 2);
StringBuilder value = new StringBuilder(n);
for(int i = 0; i < n; i++){
pad.append(padding);
}
return value.append(pad).append(s).append(pad).toString();
}
Eine einfache Lösung ohne API lautet wie folgt:
public String pad(String num, int len){
if(len-num.length() <=0) return num;
StringBuffer sb = new StringBuffer();
for(i=0; i<(len-num.length()); i++){
sb.append("0");
}
sb.append(num);
return sb.toString();
}
Java-Oneliner, keine schicke Bibliothek.
// 6 characters padding example
String pad = "******";
// testcases for 0, 4, 8 characters
String input = "" | "abcd" | "abcdefgh"
Pad Links, nicht einschränken
result = pad.substring(Math.min(input.length(),pad.length())) + input;
results: "******" | "**abcd" | "abcdefgh"
Pad Richtig, nicht einschränken
result = input + pad.substring(Math.min(input.length(),pad.length()));
results: "******" | "abcd**" | "abcdefgh"
Pad Links, Begrenzung auf Padlänge
result = (pad + input).substring(input.length(), input.length() + pad.length());
results: "******" | "**abcd" | "cdefgh"
Pad Rechts auf Limitlänge beschränken
result = (input + pad).substring(0, pad.length());
results: "******" | "abcd**" | "abcdef"
Wie wäre es mit Rekursion? Die unten angegebene Lösung ist mit allen JDK-Versionen kompatibel und es sind keine externen Bibliotheken erforderlich :)
private static String addPadding(final String str, final int desiredLength, final String padBy) {
String result = str;
if (str.length() >= desiredLength) {
return result;
} else {
result += padBy;
return addPadding(result, desiredLength, padBy);
}
}
HINWEIS : Bei dieser Lösung wird das Auffüllen angehängt. Mit einer kleinen Änderung können Sie dem Pad-Wert ein Präfix voranstellen.
Hier ist eine parallele Version für diejenigen von euch, die sehr lange Saiten haben :-)
int width = 100;
String s = "129018";
CharSequence padded = IntStream.range(0,width)
.parallel()
.map(i->i-(width-s.length()))
.map(i->i<0 ? '0' :s.charAt(i))
.collect(StringBuilder::new, (sb,c)-> sb.append((char)c), (sb1,sb2)->sb1.append(sb2));
Auffüllbeispiele in Guave:
Auffüllbeispiele in Apache Commons:
Auffüllbeispiele in JDK:
Eine einfache Lösung wäre:
package nl;
public class Padder {
public static void main(String[] args) {
String s = "123" ;
System.out.println("#"+(" " + s).substring(s.length())+"#");
}
}