[Ruby on Rails 4] 電話番号を読みやすく整形したい
よくあるユースケースのような気がするので調査。
[markdown]
– 電話番号が 10 桁もしくは 11 桁の文字列で入っている。
– オペレータが目視するため、表示時に整形したい。
というものがあって、helper をこんな形で用意し、
“`ruby: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 で利用することでひとまず目的は果たせたのですが、
“`ruby
= format_phone(@item.phone_number)
“`
電話番号の仕様に沿ってハイフンなどで区切るにはどうすれば良いのか。
## 電話番号の仕様
市外局番・市内局番が変動したりするので、Hyphen で区切るのが大変そう。
> * [総務省|電気通信番号の利用・指定|電話番号に関するQ&A](http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/q_and_a.html)
> * [総務省|電気通信番号の利用・指定|電気通信番号指定状況](http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/number_shitei.html)
さらに
> * [国内固定番号を機械的に区切る法則 – 10桁の国内固定番号系を、機械的法則… – Yahoo!知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1180690256)
>
> つまり、市外局番+市内局番までみないと、区切り(-)の位置は判別出来ないということになります。
> 数値化できる法則性が無いこと、かつ番号枯渇対策により不定期に市外局番と市内局番の区切りが変更になることもあり、上記リストをデータベースとして取込み展開することが必要になるかと思います。
ということなので、きっちり実装するとメンテナンス含めて考える必要がありそうです。
## #number_to_phone
Rails のメソッドですが __USの電話番号フォーマット__ になります。
> * [number_to_phone – リファレンス – – Railsドキュメント](http://railsdoc.com/references/number_to_phone)
> * [rails/number_helper.rb at 44260581bec06e4ce05f3dd838c8b4736fc7eb1d · rails/rails](https://github.com/rails/rails/blob/44260581bec06e4ce05f3dd838c8b4736fc7eb1d/actionview/lib/action_view/helpers/number_helper.rb#L57)
### rails-i18n
ローカライズについて。
[svenfuchs/rails-i18n](https://github.com/svenfuchs/rails-i18n) のデモアプリ内に、こんな記述を見つけました。
> * [i18n_demo_app/ja.yml at master · clemens/i18n_demo_app](https://github.com/clemens/i18n_demo_app/blob/master/config/locales/ja.yml#L105)
>
> “注意1: number_to_phone
は、まだローカライズされていません。 そして、おそらく今後もローカライズはされないのではと思います。- 少なくともコアには。 `{{globalize}}` の新しいバージョンのような新しいインターナショナライゼーションもしくは、ローカライゼーション・プラグインはこちらでお探しください。おそらく、彼らもプラグインをサポートすると思うので。”
__今後もローカライズはされない__ のでプラグインを探してとのこと。
プラグインというのが何なのかちょっと分からないので保留。
## 実装例
Ruby
> * [ハイフンなしの電話番号からハイフン付き電話番号を復元する。 – Qiita](http://qiita.com/kennyj@github/items/dde3880abb5071f649ab)
> * [ハイフン付き電話番号に分割](https://gist.github.com/kennyj/4966002)
PHP
> * [[PHP] ハイフンなしの電話番号からハイフン付き電話番号を復元する – Qiita](http://qiita.com/mpyw/items/431c0c8cb70084a74be5)
な、なるほど。(^^;)
## iTakeshi/tel_formatter
gem がありました。ありがとうございます。
> * [iTakeshi/tel_formatter: Format your telephone numbers](https://github.com/iTakeshi/tel_formatter)
[NKF](https://github.com/iTakeshi/tel_formatter/blob/master/lib/tel_formatter.rb#L43) の処理は、下記を行っているようです。
> * [nkf – UNIX/Linuxコマンド – IT専科](http://www.itsenka.com/contents/development/unix-linux/nkf.html)
>
> -m0 MIMEの解読を行いません。
> -Z -Z0 JISX0208コードのアルファベットをASCIIコードに変換します。
> -w,-w80 UTF8コード(BOMを記述しません。UTF8の場合、BOMはファイルがUTFで記述されていることを明確にするために使用されます。)で出力します
[data](https://github.com/iTakeshi/tel_formatter/tree/master/data) ディレクトリに[電話番号のマスタ](http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/number_shitei.html)を持っています。
– area_codes.txt … 市外局番(国内プレフィックス付き「0」始まりで)
– cellphone_codes.txt … 携帯電話・PHSの電話番号(090など)
– special_codes_10.txt … 10桁の 0120 などで始まる[特殊なサービス番号](http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/q_and_a.html#q6)
– special_codes_11.txt … 11桁の 0800 で始まる[特殊なサービス番号](http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/q_and_a.html#q6)
このマスタを使って REGEXP されていました。
### Rails での利用法
Rails アプリに組み込んでみます。
どこかで `require` する必要があるので、`config/application.rb` に追記してみます。
“`ruby:config/application.rb
require ‘tel_formatter’
“`
helper を書き換えました。
“`ruby: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
“`
勉強になりました。
[/markdown]