module AxleAttributes class Format class_attribute :phone_regex self.phone_regex = /\A\(\d{3}\) \d{3}-\d{4}\z/ class_attribute :url_regex self.url_regex = /\A(https?:\/\/)([-a-z0-9]+\.[-.a-z0-9:]+)(\/[^\s]+)?\z/ class_attribute :zip_regex self.zip_regex = /\A\d{5}\z/ class_attribute :postal_code_regex self.postal_code_regex = /\A(\d{5}(-\d{4})?|[A-Z0-9]{6})\z/ class << self PHONEWORDS = {"A"=>"2", "B"=>"2", "C"=>"2", "D"=>"3", "E"=>"3", "F"=>"3", "G"=>"4", "H"=>"4", "I"=>"4", "J"=>"5", "K"=>"5", "L"=>"5", "M"=>"6", "N"=>"6", "O"=>"6", "P"=>"7", "Q"=>"7", "R"=>"7", "S"=>"7", "T"=>"8", "U"=>"8", "V"=>"8", "W"=>"9", "X"=>"9", "Y"=>"9", "Z"=>"9"} def standardize_phone(phone) standardize phone, self.phone_regex do standardized = phone.chars.map { |char| PHONEWORDS[char.upcase] || char }.join('') standardized.gsub!(/\D/, '') if standardized.size == 10 standardized.gsub!(/(\d{3})(\d{3})(\d{4})/, "(\\1) \\2-\\3") standardized elsif standardized.size == 11 && standardized[0] == '1' standardized.gsub!(/1(\d{3})(\d{3})(\d{4})/, "(\\1) \\2-\\3") standardized end end end def standardize_postal_code(postal_code) standardize postal_code, postal_code_regex do standardized = postal_code.remove(/[^\-[:alnum:]]/) case standardized.length when 6 then standardized.upcase! when 9 then standardized.sub!(/\A(\d{5})(\d{4})\z/, '\\1-\\2') end standardized end end def standardize_url(website) standardize website, self.url_regex do if website =~ /^(\w*):\/\// scheme, _, resource = website.partition("://") scheme.downcase! else scheme = "http" resource = website end resource.strip! host, slash, path = resource.partition("/") host.downcase! path.gsub! ' ', '%20' path.empty? ? "#{scheme}://#{host}" : "#{scheme}://#{host}/#{path}" end end def standardize(value, regex) return value if value.blank? || value =~ regex standardized = yield(value) standardized =~ regex ? standardized : value end end end end