8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Java]半角・全角混合でも文字位置を合わせる

Last updated at Posted at 2018-10-25

はじめに

Java で半角と全角が混ざった状態で String#format を使うと文字の位置がずれてしまうことが起きました。
あまり調べても簡単に解決する方法がなかったので,パッと関数を組んでみました。

解決策

早速だけれど,以下が解決策です。
(とりあえず以下のformat()getByteLength()だけコピー&ペーストすれば解決します)

main
    public static void main(String[] args){
        //ずれるformat文
        System.out.println(String.format("%-20s", "あああああ")+" | ");
        System.out.println(String.format("%-20s", "aaaaa")+" | ");
        //ずれないformat文
        System.out.println(format("あああああ", 20)+" | ");
        System.out.println(format("aaaaa", 20)+" | ");
    }

    private static String format(String target, int length){
        int byteDiff = (getByteLength(target, Charset.forName("UTF-8"))-target.length())/2;
        return String.format("%-"+(length-byteDiff)+"s", target);
    }

    private static int getByteLength(String string, Charset charset) {
        return string.getBytes(charset).length;
    }
result
あああああ                | 
aaaaa                | 
あああああ            | 
aaaaa                | 

(Qiita へコピー&ペーストした時に|がずれたのは内緒...)
以下余談です。

ずれる理由と対策法

そもそもなぜ半角と全角でずれるのかというと,UTF-8 などで文字を表現するとbyte の数が以下のように異なるからです。

  • 日本語 : 3byte
  • 英数字 : 1byte

なので,main中のint byteDiffで調整しています。
また,以下の関数より、日本語は 3byte で、英語は 1byte であることが分かります。

analyze
    public static void main(String[] args){
        analyze("あああああ");
        analyze("aaaaa");
    }

    private static void analyze(String target){
        System.out.println("\n"+target);
        int length=20;
        System.out.println(format("length()", length)+":"+target.length());
        System.out.println(format("UTF-8 length()", length)+":"+getByteLength(target, Charset.forName("UTF-8")));
        System.out.println(format("diff", length)+":"+(getByteLength(target, Charset.forName("UTF-8"))-target.length())/2);
    }

result
あああああ
length()            :5
UTF-8 length()      :15
diff                :5

aaaaa
length()            :5
UTF-8 length()      :5
diff                :0

参考

8
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?