こんにちは。beaglesoftの真鍋です。
ココ最近はRailsを利用しています。decodeが開催されているのを横目にしながらRailsでアプリケーションを書いているのですが、むかしに比べるとすごく早く機能を実現できるなぁと感じるようになって気に入ってきました。
さて、RailsといえばGemです。便利なGemをいかに組み合わせてやりたいことを実現するかが肝です。今回は電話番号を上手に扱うGemがあったのでちょっとまとめてみました。
phoelibとは
phonelibは電話番号に関する検証を行うライブラリで、Googleが公開しているgoogle/libphonenumber: Google's common Java, C++ and JavaScript library for parsing, formatting, and validating international phone numbers. をRubyで利用できるようにしたライブラリです。
主な機能
主な機能として電話番号の検証や電話番号に関する情報を取得することができます。
電話番号の検証
電話番号の検証は国を指定して行います。ここで指定する国コードはISO 3166-1 alpha-2 - Wikipediaを参照してください。
日本の場合はjp
を指定します。
> Phonelib.valid_for_country?(03-1234-5678, :jp) => true
> Phonelib.invalid_for_country?(03-1234-5678, :jp) => false
ちょっといろいろ試してみる
# フリーダイアル >> >> Phonelib.valid_for_country?('0123-444-444', :jp) => true # IP電話 >> >> Phonelib.valid_for_country?('050-1234-5678', :jp) => true # 以下携帯電話 >> >> Phonelib.valid_for_country?('070-1234-5678', :jp) => true >> >> Phonelib.valid_for_country?('080-1234-5678', :jp) => true >> >> Phonelib.valid_for_country?('090-1234-5678', :jp) => true
電話番号のパース
電話番号文字列から電話番号をパースすることができます。
> phone = Phonelib.parse('03-1234-5670', :jp) => #<Phonelib::Phone:0x00007fcd36e70eb8 @original="03-1234-5670", @extension="", @sanitized="0312345670", @original_s="03-1234-5670", @data={"JP"=>{:id=>"JP", :country_code=>"81", :international_prefix=>"010", :national_prefix=>"0", :mobile_number_portable_region=>"true", :national=>"312345670", :format=>{:pattern=>"(\\d)(\\d{4})(\\d{4})", :national_prefix_formatting_rule=>"$NP$FG", :leading_digits=>"[36]|4(?:2(?:0|9[02-69])|7(?:0[019]|1))", :format=>"$1-$2-$3"}, :valid=>[:fixed_line], :possible=>[:premium_rate, :toll_free, :personal_number, :uan, :fixed_line]}}, @national_number="312345670"> > phone.valid? => true
正しくない電話番号をパースしたときには以下の通りvalid?
メソッドで判定できます。
> phone = Phonelib.parse('03-1234-567o', :jp) => #<Phonelib::Phone:0x00007fcd3c21a5a0 @original="03-1234-567o", @extension="", @sanitized="031234567", @original_s="03-1234-567o", @data={"JP"=>{:id=>"JP", :country_code=>"81", :international_prefix=>"010", :national_prefix=>"0", :mobile_number_portable_region=>"true", :national=>"31234567", :format=>{:pattern=>"(\\d+)(\\d{3})(\\d{4})", :format=>"$1 $2 $3"}, :valid=>[], :possible=>[:toll_free]}}, @national_number="31234567"> > phone.valid? => false
電話番号から対応する地理情報の取得
固定電話だと市外局番と市内局番により対応する地理情報を取得できます。東京都はちょっとエリアがざっくりしていますね。
Phonelib.parse('011-231-4111',:jp).geo_name => "Sapporo, Hokkaido" # 北海道 Phonelib.parse('017-722-1111',:jp).geo_name => "Aomori, Aomori" # 青森県 Phonelib.parse('019-651-3111',:jp).geo_name => "Morioka, Iwate" # 岩手県 Phonelib.parse('022-211-2111',:jp).geo_name => "Sendai, Miyagi" # 宮城県 Phonelib.parse('018-860-1111',:jp).geo_name => "Akita, Akita" # 秋田県 Phonelib.parse('023-630-2211',:jp).geo_name => "Yamagata, Yamagata" # 山形県 Phonelib.parse('024-521-1111',:jp).geo_name => "Fukushima, Fukushima" # 福島県 Phonelib.parse('029-301-1111',:jp).geo_name => "Mito, Ibaraki" # 茨城県 Phonelib.parse('028-623-2323',:jp).geo_name => "Utsunomiya, Tochigi" # 栃木県 Phonelib.parse('027-223-1111',:jp).geo_name => "Maebashi, Gunma" # 群馬県 Phonelib.parse('048-824-2111',:jp).geo_name => "Urawa, Saitama" # 埼玉県 Phonelib.parse('043-223-2110',:jp).geo_name => "Chiba, Chiba" # 千葉県 Phonelib.parse('03-5321-1111',:jp).geo_name => "Tokyo" # 東京都 Phonelib.parse('045-210-1111',:jp).geo_name => "Yokohama, Kanagawa" # 神奈川県 Phonelib.parse('025-285-5511',:jp).geo_name => "Niigata, Niigata" # 新潟県 Phonelib.parse('076-431-4111',:jp).geo_name => "Toyama, Toyama" # 富山県 Phonelib.parse('076-225-1111',:jp).geo_name => "Kanazawa, Ishikawa" # 石川県 Phonelib.parse('0776-21-1111',:jp).geo_name => "Fukui, Fukui" # 福井県 Phonelib.parse('055-237-1111',:jp).geo_name => "Kofu, Yamanashi" # 山梨県 Phonelib.parse('026-232-0111',:jp).geo_name => "Nagano, Nagano" # 長野県 Phonelib.parse('058-272-1111',:jp).geo_name => "Gifu, Gifu" # 岐阜県 Phonelib.parse('054-221-2455',:jp).geo_name => "Shizuoka, Shizuoka" # 静岡県 Phonelib.parse('052-961-2111',:jp).geo_name => "Nagoya, Aichi" # 愛知県 Phonelib.parse('059-224-3070',:jp).geo_name => "Tsu, Mie" # 三重県 Phonelib.parse('077-528-3993',:jp).geo_name => "Otsu, Shiga" # 滋賀県 Phonelib.parse('075-451-8111',:jp).geo_name => "Kyoto, Kyoto" # 京都府 Phonelib.parse('06-6941-0351',:jp).geo_name => "Osaka, Osaka" # 大阪府 Phonelib.parse('078-341-7711',:jp).geo_name => "Kobe, Hyogo" # 兵庫県 Phonelib.parse('0742-22-1101',:jp).geo_name => "Nara, Nara" # 奈良県 Phonelib.parse('073-432-4111',:jp).geo_name => "Wakayama, Wakayama" # 和歌山県 Phonelib.parse('0857-26-7111',:jp).geo_name => "Tottori, Tottori" # 鳥取県 Phonelib.parse('0852-22-5111',:jp).geo_name => "Matsue, Shimane" # 島根県 Phonelib.parse('086-224-2111',:jp).geo_name => "Okayama, Okayama" # 岡山県 Phonelib.parse('082-228-2111',:jp).geo_name => "Hiroshima, Hiroshima" # 広島県 Phonelib.parse('083-922-3111',:jp).geo_name => "Yamaguchi, Yamaguchi" # 山口県 Phonelib.parse('088-621-2500',:jp).geo_name => "Tokushima, Tokushima" # 徳島県 Phonelib.parse('087-831-1111',:jp).geo_name => "Takamatsu, Kagawa" # 香川県 Phonelib.parse('089-941-2111',:jp).geo_name => "Matsuyama, Ehime" # 愛媛県 Phonelib.parse('088-823-1111',:jp).geo_name => "Kochi, Kochi" # 高知県 Phonelib.parse('092-651-1111',:jp).geo_name => "Fukuoka, Fukuoka" # 福岡県 Phonelib.parse('0952-24-2111',:jp).geo_name => "Saga, Saga" # 佐賀県 Phonelib.parse('095-824-1111',:jp).geo_name => "Nagasaki, Nagasaki" # 長崎県 Phonelib.parse('096-383-1111',:jp).geo_name => "Kumamoto, Kumamoto" # 熊本県 Phonelib.parse('097-536-1111',:jp).geo_name => "Oita, Oita" # 大分県 Phonelib.parse('0985-26-7111',:jp).geo_name => "Miyazaki, Miyazaki" # 宮崎県 Phonelib.parse('099-286-2111',:jp).geo_name => "Kagoshima, Kagoshima" # 鹿児島県 Phonelib.parse('098-866-2333',:jp).geo_name => "Naha, Okinawa" # 沖縄県
ActiveRecordのValidatorとして利用
ActiveRecordでPhonelibをValidatorとして利用するときは以下のように利用します。
class Company < ApplicationRecord # phone_noという列を定義しているとします validates :phone_no, phone: {allow_blank: true, countries: [:jp]} end c = Company.first c.phone_no = '031234567a' c.valid? => false c.errors.full_messages => ["電話番号は不正な値です"]
なお、検証対象の国が日本など固定の場合にはconfig/initializer/phonelib.rb
に指定することで省略することができます。
$ touch config/initializers/phonelib.rb $ echo 'Phonelib.default_country = "JP"' >> config/initializers/phonelib.rb
その他設定を記載することもできますが、詳細はREADMEを参照してください。
まとめ
今回ざっと紹介した以外にもいろいろな機能があるのですが、Rubyで電話番号を扱う上ではこのライブラリが便利ではないでしょうか。

プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで (Software Design plusシリーズ)
- 作者: 伊藤淳一
- 出版社/メーカー: 技術評論社
- 発売日: 2017/11/25
- メディア: 大型本
- この商品を含むブログを見る