Created
July 1, 2011 10:16
-
-
Save galetahub/1058239 to your computer and use it in GitHub Desktop.
Phone numbers parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# PhoneNumber parser | |
# Example: | |
# p = PhoneNumber.new('+380971265128') | |
# => #<PhoneNumber:0xb37b404 @value="380971265128", @locale=:uk, @pattern=[38, "097", ["126", "51", "28"]]> | |
# p.valid? | |
# => true | |
# p.to_s | |
# => "38 (097) 126-51-28" | |
# p.to_s(:prefix => true) | |
# => "+38 (097) 126-51-28" | |
# p.to_s(:format => "(%o) %n", :spliter => ' ') | |
# => "(097) 126 51 28" | |
# p.to_i | |
# => 380971265128 | |
# PhoneNumber.new(380971265128).to_s(:prefix => true) | |
# => "+38 (097) 126-51-28" | |
# | |
# ActiveRecord | |
# | |
# composed_of :phone, | |
# :class_name => 'PhoneNumber', | |
# :mapping => %w(phone_number to_i) | |
# | |
class PhoneNumber | |
TABLE = { | |
:uk => { | |
:codes => %W( 039 050 063 066 067 068 091 092 093 094 095 096 097 098 099 ), | |
:regex => /^\+?(\d{0,2})(\d{3})(\d{3})(\d{2})(\d{2})$/, | |
:country => 38, | |
:format => "%c (%o) %n" | |
} | |
} | |
attr_accessor :locale, :value | |
def initialize(phone, options = {}) | |
@value = phone.to_s.downcase.scan(/\d+/).join | |
@locale = (options[:locale] || I18n.locale).to_sym | |
@pattern = self.class.parse(@value, @locale) | |
end | |
# Check pattern, country and operator code | |
def valid? | |
@pattern && table[:country] == @pattern[0] && table[:codes].include?(@pattern[1]) | |
end | |
# Creates a phone number based on pattern provided. Defaults to US (NANP) formatting (111) 111-1111. | |
# | |
# Symbols: | |
# %c - country code | |
# %o - operator | |
# %n - phone number | |
# | |
def to_s(options = {}) | |
if valid? | |
options = { :prefix => false, :spliter => "-", :format => table[:format] }.merge(options) | |
str = (options[:prefix] ? "+" : '') + options[:format] | |
arr = [@pattern[0], @pattern[1], @pattern[2].join(options[:spliter])] | |
[ /%c/, /%o/, /%n/ ].each_with_index { |regex, index| str = str.gsub(regex, arr[index].to_s) } | |
str | |
end | |
end | |
def to_i | |
if valid? | |
@pattern.join.to_i | |
end | |
end | |
def table | |
TABLE[@locale] | |
end | |
# Parse phone number by given regex | |
# Return a array of parsed values (prefix, operator, phone number ...) | |
# | |
def self.parse(value, locale = nil) | |
locale ||= I18n.locale | |
table = TABLE[locale.to_sym] | |
if m = value.match( table[:regex] ) | |
[ (m[1].blank? ? table[:country] : m[1]).to_i, m[2], m.to_a.slice(3..-1) ] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Country code for Ukraine is +380 not +38.