[Ruby on Rails 4] 電話番号を読みやすく整形したい

よくあるユースケースのような気がするので調査。

  • 電話番号が 10 桁もしくは 11 桁の文字列で入っている。
  • オペレータが目視するため、表示時に整形したい。

というものがあって、helper をこんな形で用意し、

app/helpers/items_helper.rb
module ItemsHelper
  def format_phone(str)
    return str if str.blank?

    case str.size
    when 10
      str.gsub(/(\d{2})(\d{4})(\d{4})/, '\1_\2_\3')
    when 11
      str.gsub(/(\d{3})(\d{4})(\d{4})/, '\1_\2_\3')
    else
      str
    end
  end
end

view で利用することでひとまず目的は果たせたのですが、

= format_phone(@item.phone_number)

電話番号の仕様に沿ってハイフンなどで区切るにはどうすれば良いのか。

Contents

電話番号の仕様

市外局番・市内局番が変動したりするので、Hyphen で区切るのが大変そう。

さらに

つまり、市外局番+市内局番までみないと、区切り(-)の位置は判別出来ないということになります。
数値化できる法則性が無いこと、かつ番号枯渇対策により不定期に市外局番と市内局番の区切りが変更になることもあり、上記リストをデータベースとして取込み展開することが必要になるかと思います。

ということなので、きっちり実装するとメンテナンス含めて考える必要がありそうです。

#number_to_phone

Rails のメソッドですが USの電話番号フォーマット になります。

rails-i18n

ローカライズについて。
svenfuchs/rails-i18n のデモアプリ内に、こんな記述を見つけました。

“注意1: number_to_phoneは、まだローカライズされていません。 そして、おそらく今後もローカライズはされないのではと思います。- 少なくともコアには。 {{globalize}} の新しいバージョンのような新しいインターナショナライゼーションもしくは、ローカライゼーション・プラグインはこちらでお探しください。おそらく、彼らもプラグインをサポートすると思うので。”

今後もローカライズはされない のでプラグインを探してとのこと。
プラグインというのが何なのかちょっと分からないので保留。

実装例

Ruby

PHP

な、なるほど。(^^;)

iTakeshi/tel_formatter

gem がありました。ありがとうございます。

NKF の処理は、下記を行っているようです。

-m0 MIMEの解読を行いません。
-Z -Z0 JISX0208コードのアルファベットをASCIIコードに変換します。
-w,-w80 UTF8コード(BOMを記述しません。UTF8の場合、BOMはファイルがUTFで記述されていることを明確にするために使用されます。)で出力します

data ディレクトリに電話番号のマスタを持っています。

  • area_codes.txt … 市外局番(国内プレフィックス付き「0」始まりで)
  • cellphone_codes.txt … 携帯電話・PHSの電話番号(090など)
  • special_codes_10.txt … 10桁の 0120 などで始まる特殊なサービス番号
  • special_codes_11.txt … 11桁の 0800 で始まる特殊なサービス番号

このマスタを使って REGEXP されていました。

Rails での利用法

Rails アプリに組み込んでみます。
どこかで require する必要があるので、config/application.rb に追記してみます。

config/application.rb
require 'tel_formatter'

helper を書き換えました。

app/helpers/items_helper.rb
module ItemsHelper
  def format_phone(str)
    return str if str.blank?

    case str.size
    when 10..11
      TelFormatter.format(str)
    else
      str
    end
  end
end

勉強になりました。