phpで半角カナ入り文字列を文字数ではなく文字幅(バイト数)で変換・短縮する

はてなブックマーク - phpで半角カナ入り文字列を文字数ではなく文字幅(バイト数)で変換・短縮する
このエントリーをはてなブックマークに追加
Share on Facebook

こんなことが必要になった

  • 半角カナを含む日本語文字列に対して、10文字以上のときは短縮したい。
  • 文字数ではなく幅(バイト数)でそろえたい。
  • 短縮した場合は"..."を付与する。

ということで、がんばってやってみた。

mb_strimwidthというマルチバイトに対応した指定した幅で文字列を丸める関数を使う。

string mb_strimwidth  ( string $str  , int $start  , int $width  [, string $trimmarker  [, string $encoding  ]] )

公式はこんな感じ
引き数は、1:文字列、2:開始位置、3:短縮する幅、4:短縮した場合に追加する文字列、5:文字エンコーディング
となっている。

$string = mb_strimwidth($string,0,10,"...");

あれ、これで解決じゃん?
と思ったけどそう簡単にはいかなかった。

どうやら、半角カナを2バイトとして数えたりして、綺麗に同じ幅で短縮されない。
色々しらべてみると、どうもEUC-JPの半角カナとSJISの半角カナは違う文字でEUC-JPの半角カナは2バイト分の幅でカウントされてしまうらしい。
(使ったサーバの内部文字エンコーディングはEUC-JP)
見た目は一緒だけど違う文字ってわけ分からないけど、決まってるからしょうがない。

じゃあSJISとしてやってみればいいじゃんということで、変換してからやってみた。

$string = mb_convert_encoding($string,"SJIS-win","EUCJP-win");
$string = mb_strimwidth($string,0,10,"...","SJIS-win");
$string = mb_convert_encoding($string,"EUCJP-win","auto");

うーん、これでも結果は変わらない・・・。

ここでハマったけど、解決した。

ネックとなっていたのはやっぱり
「EUC-JPの半角カナとSJISの半角カナは違う文字」
ということ!
違う文字だからエンコード変換で相互に変換できない!

じゃあどうしよっかということで悩んで導き出したのがこの方法
EUC-JPの半角カナを一旦全角カナにしてからSJISの半角カナに戻す
これでうまくできた!!
ちなみに半角⇒全角⇒半角にはmb_convert_kanaを使用。

ということで一連のソースはこんな感じです。

$string = mb_convert_encoding($string,"SJIS-win","EUCJP-win");    //EUC-JP⇒SJISに変換
$string = mb_convert_kana($string,"KAV","SJIS-win");            //半角文字列を全角文字列に変換
$string = mb_convert_kana($string,"ka","SJIS-win");                //全角文字列を半角文字列に変換
$string = mb_strimwidth($string,0,10,"...","SJIS-win");            //文字列を短縮
$string = mb_convert_encoding($string,"EUCJP-win","auto");        //SJIS⇒EUC-JPに変換

コメントをどうぞ

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <img localsrc="" alt="">