【Java】マルチバイトを含んだ文字列を指定バイト数で切る

マルチバイトを含んだ文字列を指定バイト数で切って、切った場合に三点リーダを付与する関数を作りました。半端な場合(マルチバイト文字の途中で切れる)は、その文字ごと切り捨てます。

方法としては文字列を一文字ずつ取り出して、それがシングルバイトなのかマルチバイトなのかを判定します。

判定はStringクラスの getBytes(StandardCharsets.UTF_8).length が1ならシングルバイトとしています。

なお三点リーダも文字列と考慮するので、マルチバイト一文字分を含めても切る必要がない場合は何もしないものとします。

実装

共通クラス

StringUtils.java

staticメソッドで定義しました。これをコピってそのまま使えます。

public class StringUtils {
    /**
     * 文字列を指定バイト数で切って、切った場合三点リーダを付与する
     * @param value
     * @param byteLength
     * @return
     */
    public static String truncate(String value, int byteLength) {
        if(value == null) {
            return null;
        }

        if(getByte(value) <= byteLength + 2) {
            return value;
        }

        String ret = "";
        int b = 0;
        for(int i = 0; i < value.length(); i++) {
            String target = value.substring(i, i + 1);
            if(target.getBytes(StandardCharsets.UTF_8).length == 1) {
                b++;
            } else{
                b += 2;
            }

            if(b >= byteLength + 2) {
                ret += "…";
                break;
            }

            ret += target;
        }

        return ret;
    }

    /**
     * 文字列のバイト数を取得
     * @param value
     * @return
     */
    private static int getByte(String value) {
        int ret = 0;

        for(int i = 0; i < value.length(); i++) {
            // 文字列を一文字ずつ取り出して、それがシングルバイトなのかマルチバイトなのかを判定する
            // シングルバイトの場合1を、マルチバイトの場合2を加算する
            String target = value.substring(i, i + 1);
            if (target.getBytes(StandardCharsets.UTF_8).length == 1) {
                ret++;
            } else {
                ret += 2;
            }
        }

        return ret;
    }
}

※String.getBytes(StandardCharsets.UTF_8)は文字列をUTF-8と解釈して、バイト数を取得します。なのでUTF-8以外の文字列の場合はうまく動かないかもしれません。

実行例

いろいろな文字列を6バイトで切ってみます。

String test1 = "あいうえお";
System.out.println(test1);
System.out.println(StringUtils.truncate(test1, 6));
System.out.println("------");

String test2 = "ABCDEFGHIJ";
System.out.println(test2);
System.out.println(StringUtils.truncate(test2, 6));
System.out.println("------");

String test3 = "かきTEST";
System.out.println(test3);
System.out.println(StringUtils.truncate(test3, 6));
System.out.println("------");

String test4 = "さAしBすCせDそE";
System.out.println(test4);
System.out.println(StringUtils.truncate(test4, 6));
System.out.println("------");

String test5 = "ABCたちつDEFG";
System.out.println(test5);
System.out.println(StringUtils.truncate(test5, 6));
System.out.println("------");

実行結果

実行結果は以下のようになります。

あいうえお
あいう…
------
ABCDEFGHIJ
ABCDEF…
------
かきTEST
かきTEST
------
さAしBすCせDそE
さAしB…
------
ABCたちつDEFG
ABCた…

スマートフォンなどの限られたスペースで表示する際は特に使えるかと思います。

コメント

このブログの人気の投稿

docker-compose up で proxyconnect tcp: dial tcp: lookup proxy.example.com: no such host

docker-compose で起動したweb、MySQLに接続できない事象

【PHP】PHP_CodeSnifferを使う(コーディングルールのカスタマイズ)