カクカクしかじか

技術的なアレコレ

Rubyで半角カナを1文字、全角カナを2文字でカウントする方法

概要

全角カナなら2文字・半角カナなら1文字でカウントしてデータを扱いたいケースがあったのでその調査メモ📝
単純に文字列に対して '文字列'.size をしても全角半角で区別出来ないので、バイトサイズでカウントしてみることにしました。
(半角カナ:1文字1バイト/全角カナ:1文字2バイト)

検証バージョン

Ruby 2.6.5

結論

Rubyのデフォルトの文字コードである UTF-8 だとバイトサイズが半角カナでも全角カナでも同じサイズになってしまうようなので、 CP932 に変換してバイトサイズを測ると全角を半角の倍のサイズで計測出来たので目的を達成出来ました🎉
(バイト数のカウントになってるので、正確に言うと文字数カウントとは違うのかもしれない...)

UTF-8でbytesizeメソッドを使った場合

$ ('カタカナ').bytesize
=> 12
$ ('カタカナ').bytesize
=> 12

CP932でbytesizeメソッドを使った場合

$ require 'nkf'
$ NKF::nkf('-W --oc=cp932', 'カタカナ').bytesize
=> 8
$ NKF::nkf('-W --oc=cp932', 'カタカナ').bytesize
=> 4

おまけ

全角から半角の変換とその逆をよく分かってなかったのでメモ✍️

  • -w で出力を UTF-8 に指定。
  • -Z4は全角カナを半角カナに変換するオプションなのですが、NKFのメソッドでは同じオプションでその逆もイケそう。
$ require 'nkf'
$ NKF::nkf('-w -Z4', 'カタカナ')
=> "カタカナ"
$ NKF::nkf('-w -Z4', 'カタカナ')
=> "カタカナ"

公式ドキュメント

docs.ruby-lang.org