Javaで文字列を埋め込むにはどうすればよいですか?


431

Javaで文字列を埋め込む簡単な方法はありますか?

StringUtilのようなAPIにあるべきもののように見えますが、これを行うものは何も見つかりません。


apache関数と文字列フォーマッターの問題については、apache関数の方が明確で読みやすいことは間違いありません。関数名でフォーマッターをラップすることは理想的ではありません。
Terra Caines、2010

回答:


188

ApacheはStringUtilsいくつかの方法があります:leftPadrightPadcenterrepeat

しかししてくださいことに注意してください-他の人がで述べたと証明しているようこの回答 - String.format()およびFormatterJDKのクラスは、より良いオプションです。コモンズコード上で使用します。


91
java.util.Formatter(およびString.format())がこれを行います。JDKバージョンが機能する場合は、JDKが外部ライブラリよりも常に優先されるようにします。
cletus 2008

6
いくつかの理由から、私は今、Apache CommonsよりGuavaを好みます。この回答は、グアバでそれを行う方法を示しています
Jonik、2012年

1
@ジョニックはあなたの理由のいくつかをリストアップしてもらえますか?APIはほとんど同じように見えます。
glen3b 2014年

3
@ glen3b:これらの文字列パディングヘルパーのような個々のユーティリティでは、どのlibを使用しても違いはありません。とはいえ、グアバは全体的に、さまざまなApache Commonsプロジェクト(Commons Lang、Commons Collections、Commons IOなど)の対応物よりも、よりモダンで、よりクリーンで、ドキュメント化されています。それはまた、その多くがSOで活動している本当に賢い人(Kevin Bourrillion et al)によって構築されています。私自身、結局数年前にさまざまなApache CommonsライブラリをGuavaに置き換えることになり、後悔はありませんでした。
Jonik 2014年


634

Java 1.5以降String.format()、特定の文字列を左/右に埋め込むために使用できます。

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) + "*");
}

そして出力は:

Howto               *
               Howto*

39
他の文字(スペースではない)でlpadする必要がある場合はどうなりますか?String.formatでも可能ですか?私はそれを機能させることができません...
グイド

6
私の知る限りString.Formatの()を参照してください、それはそれをコーディングするには余りにも難しいことではありませんことはできませんrgagnon.com/javadetails/java-0448.html(第二例)
RealHowTo

61
Nullw0rm @、あなたは...彼は自分自身をクレジットされますのでRealHowToは、あまりにもrgagnon.comの著者であることに注意して、rgagnon.comに言及している場合
コリン・ピカード

3
少なくとも私のJVMでは、「#」は機能しません。「-」で結構です。(#を削除するだけです)。これはフォーマッタのドキュメントと一致しているかもしれません、私は知りません。「 '#' '\ u0023'出力には代替フォームを使用する必要があります。フォームの定義は変換によって指定されます。」
gatoatigrado 2011年

6
素晴らしい答えをありがとう。でも疑問はあり1$ますか?@leoは使用しない非常によく似た答えを出し、1$明らかに同じ効果があります。違いはありますか?
FABRICIOマット

257

10文字までのパディング:

String.format("%10s", "foo").replace(' ', '*');
String.format("%-10s", "bar").replace(' ', '*');
String.format("%10s", "longer than 10 chars").replace(' ', '*');

出力:

  *******foo
  bar*******
  longer*than*10*chars

パスワードの文字に「*」を表示:

String password = "secret123";
String padded = String.format("%"+password.length()+"s", "").replace(' ', '*');

出力の長さはパスワード文字列と同じです:

  secret123
  *********

50
スペースを含む文字列を渡さないことを私たち全員が覚えている限り...:D
leviathanbadger

4
@ aboveyou00を使用しています。これは、leoが提供する例を含む、スペースを含む文字列の恐ろしい解決策です。入力文字列の元のパディングによって指定されたパディング長を超えない限り、文字列を左側または右側にパディングするソリューションは、出力に表示されるとおりに入力文字列を変更しないでください。
ブライアンワルシャワ2015年

3
スペースの問題を認めます。.replace(' ', '*')むしろ、パディングの効果を示すことを目的としていました。いずれにしても、パスワード非表示式にはこの問題はありません...ネイティブJava機能を使用した左右のパディング文字列のカスタマイズに関するより良い回答については、私の別の回答を参照してください。
レオ

文字列に単一のスペースしか含まれておらず、別の文字でパディングしたい場合は、regex replaceをlook String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")String.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
before


33

簡単なもの:

値は文字列でなければなりません。そうでない場合は、文字列に変換します。好き"" + 123Integer.toString(123)

// let's assume value holds the String we want to pad
String value = "123";

部分文字列は、値の長さcharインデックスから始まり、パディングされた最後の長さまで:

String padded="00000000".substring(value.length()) + value;

// now padded is "00000123"

より正確な

パッド右:

String padded = value + ("ABCDEFGH".substring(value.length())); 

// now padded is "123DEFGH"

左パッド:

String padString = "ABCDEFGH";
String padded = (padString.substring(0, padString.length() - value.length())) + value;

// now padded is "ABCDE123"

24

見てくださいorg.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)

しかし、アルゴリズムは非常にシンプルです(charのサイズまで右にパディングします)。

public String pad(String str, int size, char padChar)
{
  StringBuffer padded = new StringBuffer(str);
  while (padded.length() < size)
  {
    padded.append(padChar);
  }
  return padded.toString();
}

11
Java 1.5以降では、StringBufferの代わりにStringBuilderを使用する価値があることに注意してください。
Jon Skeet

21

Apache CommonsのほかにString.format、単純なパディング(スペースなど)を処理できるものも参照してください。


17
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...

4
注意:関数名を逆にします。実行すると表示されます。
青みがかっ

さらに、元のstrにスペースが含まれている場合、これは機能しません
Steven Shaw

@StevenShaw私が間違っていない場合、置換は元のをターゲットにしないstrので、これは正しいです。
mafu 2014年

3
慣例として、関数名には大文字を使用しないでください。
principal-ideal-domain

ときであるとして、文字列を返すに欠けている条件はあります(length - str.length())ですか0?フォーマッタは、フォーマット文字列であるFormatFlagsConversionMismatchExceptionときをスローし%0sます。
Devin Walters

7

これを理解するには少し時間がかかりました。本当の鍵は、そのFormatterのドキュメントを読むことです。

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

なぜ終わりをそんなに複雑にするのですか?String hex = String.format( "%032x"、digest);を実行しただけかもしれません。そして、まったく同じ結果が得られました。不必要なreplace()がなく、$を使用して特定の変数にアクセスする必要があります(結局1つしかありません。)
ArtOfWarfare

@ArtOfWarfareフェアポイント。もともと誰かが別の質問で16進数の値にパディングを要求したのですが、フォーマッターのドキュメントへのリンクがあることがわかりました。完全にするために複雑です。
Nthalk 2014年

6

このスレッドは古いもので、元の質問は簡単な解決策でしたが、本当に速いと思われる場合は、char配列を使用する必要があります。

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

フォーマッタソリューションは最適ではありません。フォーマット文字列を作成するだけで、2つの新しい文字列が作成されます。

apbのソリューションは、sbをターゲットサイズで初期化し、以下を置き換えることで改善できます。

StringBuffer padded = new StringBuffer(str); 

StringBuffer padded = new StringBuffer(pad); 
padded.append(value);

sbの内部バッファーの拡大を防ぎます。


場合StringBuffer(この場合には真である)一度に複数のスレッドがアクセスすることができない、あなたが使用する必要がありますStringBuilder(JDK1.5 +中)は、同期のオーバーヘッドを回避します。
glen3b 2014年

5

次に、右にパディングする別の方法を示します。

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

5

Java 11以降、String.repeat(int)を使用して、指定された文字列を左/右に埋め込むことができます。

System.out.println("*".repeat(5)+"apple");
System.out.println("apple"+"*".repeat(5));

出力:

*****apple
apple*****

1
Java 11のベストアンサー!
Nagy Attila

4

パディングデータを保持することにより、毎回再構築するのではなく、呼び出しごとのオーバーヘッドを削減できます。

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

}

別の方法として、結果の長さをpad(...)メソッドのパラメーターにすることができます。その場合、コンストラクタではなく、そのメソッドで非表示のパディングの調整を行います。

(ヒント:追加のクレジットとして、スレッドセーフにします!;-)


1
安全でない公開を除いて、これはスレッドセーフです(当然、フィールドをfinalにします)。+の前に部分文字列を追加することでパフォーマンスが改善されると思います。
トム・ホーティン-タックライン2008

3

Dzoneでこれを見つけました

ゼロで埋める:

String.format("|%020d|", 93); // prints: |00000000000000000093|

これは、外部ライブラリをインストールする必要がない、シンプルで簡潔な答えになります。
Wong Jia Hau

2

組み込みのStringBuilderのappend()およびinsert()メソッドを使用して、可変文字列長のパディングを行うことができます。

AbstractStringBuilder append(CharSequence s, int start, int end) ;

例えば:

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

2

これは機能します:

"".format("%1$-" + 9 + "s", "XXX").replaceAll(" ", "0")

文字列XXXを最大9文字まで空白で埋めます。その後、すべての空白は0に置き換えられます。空白と0を好きなように変更できます...


空の文字列を悪用する代わりに、staticメソッドを呼び出す必要がありString.format(…)ます。ソースコードに4文字を保存しても、読みやすさを損なう価値はありません。
ホルガー

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

2

別の文字列に連結する前に左/右のパディング(または接頭辞/接尾辞の文字列またはスペース)を与える必要があり、長さやif条件をテストしたくない場合のために、答えを残しておきましょう。

選択した回答と同じように、私はStringUtilsApache Commons を好みますが、この方法を使用します。

StringUtils.defaultString(StringUtils.leftPad(myString, 1))

説明:

  • myString:入力した文字列、nullにすることができます
  • StringUtils.leftPad(myString, 1):文字列がnullの場合、このステートメントもnullを返します
  • 次にdefaultString、空の文字列を指定して連結ヌルを防止するために使用します

2

@ck@Marlon Tarakの回答がを使用する唯一の回答ですchar[]。1秒あたりのパディングメソッドへの複数の呼び出しがあるアプリケーションでは、これが最良のアプローチです。ただし、これらは配列操作の最適化を利用しておらず、私の好みのために少し上書きされています。これはループなしで行うことができます。

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

簡単なテスト方法:

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

出力:

012345678901234567890123456789
cats                          
                          cats
                cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too long for your own good, buddy 

1
を呼び出して続けてを呼び出す代わりに、を使用getCharsしてStringその内容をout配列に直接コピーできます。実装をに簡略化することも検討します。これはより多くの作業を行うように見えますが、実際にはJVMがデフォルトのゼロ充填を排除することを可能にします。source.toCharArray()System.arraycopychar[] 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);fill
ホルガー

1

java.util.Formatter左と右のパディングを行います。奇妙なサードパーティの依存関係は必要ありません(非常に簡単なもののために追加する必要があります)。

[詳細を省略し、この投稿を「コミュニティウィキ」にしました。これは私が必要としているものではないためです。]


4
同意しません。大規模なJavaプロジェクトでは通常、文字列の操作を大量に行うため、読みやすさの向上とエラーの回避は、Apache Commons Langを使用する価値があります。someString.subString(someString.indexOf(startCharacter)、someString.lastIndexOf(endCharacter))のようなコードはご存じのとおり、これはStringUtilsで簡単に回避できます。
Bananeweizen

1

通常、すべての文字列操作は非常に効率的である必要があります。特に、大きなデータセットを扱う場合はそうです。plsql padコマンドで得られるものに似た、高速で柔軟性のあるものが欲しかった。また、1つの小さなことのために巨大なlibを含めたくありません。これらの考慮事項では、これらのソリューションはどれも満足のいくものではありませんでした。これは私が思いついたソリューションで、ベンチマークの結果が最高でした。誰かが改善できる場合は、コメントを追加してください。

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;
    }
}
  • String.toCharArray()で呼び出され、結果は新しいString((char [])result)でStringに変換できることに注意してください。その理由は、複数の操作を適用する場合、すべての操作をchar []で実行でき、フォーマット間の変換を継続する必要がないためです-舞台裏では、Stringはchar []として格納されます。これらの操作がStringクラス自体に含まれていた場合、速度とメモリの点で2倍の効率性が得られます。

これは確かに最も効率的な方法のようです
David Lilljegren

1

この機能を使用します。

private String leftPadding(String word, int length, char ch) {
   return (length > word.length()) ? leftPadding(ch + word, length, ch) : word;
}

使い方?

leftPadding(month, 2, '0');

出力:01 02 03 04 .. 11 12


1

多くの人がいくつかの非常に興味深いテクニックを持っていますが、私はそれをシンプルにしておくのが好きなので、これを使います:

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

2
これは非常に非効率的です
。StringBuilderを

長さはすでにわかっているので、インスタンス化するときにその分多くのスペースを割り当てるようにStringBuilderに指示する必要があります。
アリエル

@アリエルは面白いとおっしゃっていますが、今日はそのことについて誰かと話していただけなのです。
Aelphaeis

0

APIを使用しない簡単なソリューションは次のとおりです。

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

0

Java oneliners、豪華なライブラリはありません。

// 6 characters padding example
String pad = "******";
// testcases for 0, 4, 8 characters
String input = "" | "abcd" | "abcdefgh"

パッド左、制限しない

result = pad.substring(Math.min(input.length(),pad.length())) + input;
results: "******" | "**abcd" | "abcdefgh"

パッド右、制限しない

result = input + pad.substring(Math.min(input.length(),pad.length()));
results: "******" | "abcd**" | "abcdefgh"

左にパッド、パッドの長さに制限

result = (pad + input).substring(input.length(), input.length() + pad.length());
results: "******" | "**abcd" | "cdefgh"

パッド右、パッド長さに制限

result = (input + pad).substring(0, pad.length());
results: "******" | "abcd**" | "abcdef"

0

再帰を使用するのはどうですか?以下の解決策は、すべてのJDKバージョンと互換性があり、外部ライブラリは必要ありません:)

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

:このソリューションでは、パディングを追加します。少し調整して、パディング値の前に付けることができます。


0

これは非常に長い文字列を持つあなたのための並列バージョンです:-)

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

0

-1

簡単な解決策は次のとおりです。

package nl;
public class Padder {
    public static void main(String[] args) {
        String s = "123" ;
        System.out.println("#"+("     " + s).substring(s.length())+"#");
    }
}

-1

これはどのように

文字列は "hello"で、必要なパディングは15で、 "0"の左パディングがあります

String ax="Hello";
while(ax.length() < 15) ax="0"+ax;

10
これは最大15個の新しい文字列を生成します。
claj 2014

@clajはい、しかしこれ
ruffin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.