The (admittedly crazy) goal of this Gem is to be able to format/split all phone numbers in the world.
Used in: airbnb.com, restorm.com, socialcam.com, zendesk.com (and many, many others).
There’s also a Rails wrapper: https://github.com/joost/phony_rails.
This gem normalizes, formats and splits E164 phone numbers. A valid E164 phone number must include a country code.
E164 numbers are international numbers with a country dial prefix, usually an area code and a subscriber number. For example, the Austalian number number +61 412 345 678
can be broken down into the following components:
- a country code of
61
- a mobile number denoted by the
4
(specific to Australia) - a subscriber number of
12 345 678
Learn more about E164 numbers here.
Currently handles Abhas, Afghan, Algerian, Argentinan, Austrian, Australian, Azerbaijani, Belgian, Brazilian, Cambodian, Chilean, Chinese, Croatian, Cuban, Cypriot, Czech, Danish, Dutch, Egyptian, El Salvadorian, Estonian, French, German, Ghanan, Gibraltar, Greek, Haiti, Hong Kong, Hungarian, Indian, Iran, Irish, Israel, Italian, Kazakh, Lithuanian, Luxembourgian, Malaysian, Malta, Mexican, Monaco, Morocco, New Zealand, Nigerian, Norwegian, Peruvian, Polish, Romanian, Russian, Rwandan, Seychelles, Singapore, Slovakian, South African, South Korean, South Osetian, Spanish, Sri Lankan, Sudan, Swedish, Swiss, Thailand, Tunisian, Turkish, Liechtenstein, UK, US, Venezuelan, and Vietnamese numbers.
And to some extent, all others. Just try if it works for you.
If it doesn’t, please enter an issue.
Using with Rails? Check out: https://github.com/joost/phony_rails.
With Bundler:
Append gem 'phony'
to your Gemfile
and bundle install
it.
Without Bundler:
Run gem install phony
from your command line.
“Plausible” means “seems reasonable or probable”, not implying 100% correctness on a true
, but implying 100% correctness on a false
return value. So if this returns true
, it might still be not a plausible number. If it returns false
, it is definitely not an E164 conform number.
Use this method in combination with normalize
for saving it into the database. Also see floere#35 for a discussion on the topic.
Note that you can add constraints to the plausibility check like the country code, cc
, and the national destination code, ndc
. Use the options to further limit the plausibility range. For example, only allow a small number of countries.
Phony.plausible?('0000000').should be_false
Phony.plausible?('hello').should be_false
Phony.plausible?('+41 44 111 22 33').should be_true
Phony.plausible?('+41 44 111 22 33', cc: '41').should be_true
Phony.plausible?('+41 44 111 22 33', ndc: '44').should be_true
Phony.plausible?('+41 44 111 22 33', cc: '1').should be_false
Phony.plausible?('+41 44 111 22 33', ndc: '43').should be_false
Phony.plausible?('+41 44 111 22 33', cc: '41', ndc: '44').should be_true
Phony.plausible?('+41 44 111 22 33', cc: /4(0|2)/, ndc: /4(4|5)/).should be_false
Phony.plausible?('+41 44 111 22 33', cc: /4(0|1)/, ndc: /4(4|5)/).should be_true
This will often raise an error if you try normalizing a non E164-izable number (a number that does not contain enough information to be normalized into an E164 conform number). Use Phony.plausible?
for checking if it can be normalized first.
Phony.normalize('41443643533').should == '41443643533'
Phony.normalize('+41 44 364 35 33').should == '41443643533'
Phony.normalize('+41 44 364 35 33').should == '41443643533'
Phony.normalize('+41 800 11 22 33').should == '41800112233'
Phony.normalize('John: +41 44 364 35 33').should == '41443643533'
Phony.normalize('1 (703) 451-5115').should == '17034515115'
Phony.normalize('1-888-407-4747').should == '18884074747'
Phony.normalize('1.906.387.1698').should == '19063871698'
Phony.normalize('+41 (044) 364 35 33').should == '41443643533'
Aliased as Phony.formatted(number_string)
.
Phony.format('41443643532').should == '+41 44 364 35 32'
Phony.format('41800112233').should == '+41 800 11 22 33'
Phony.format('43198110').should == '+43 1 98110'
Phony.format('18705551122').should == '+1 870 555 1122'
Phony.format('18091231234', :format => :international).should == '+1 809 123 1234'
Phony.format('43198110', :format => :international).should == '+43 1 98110'
Phony.format('43198110', :format => :international_absolute).should == '+43 1 98110'
Phony.format('33142278186', :format => :+).should == '+33 1 42 27 81 86'
Phony.format('43198110', :format => :international_relative).should == '0043 1 98110'
Phony.format('4233841148', :format => :international_relative).should == '00423 384 11 48'
Phony.format('18091231234', :format => :international, :spaces => '').should == '+18091231234'
Phony.format('43198110', :format => :international, :spaces => '').should == '+43198110'
Phony.format('43198110', :format => :international_absolute, :spaces => '').should == '+43198110'
Phony.format('33142278186', :format => :+, :spaces => '').should == '+33142278186'
Phony.format('43198110', :format => :international_relative, :spaces => '').should == '0043198110'
Phony.format('4233841148', :format => :international_relative, :spaces => '').should == '004233841148'
Phony.format('18091231234', :format => :international, :spaces => :-).should == '+1-809-123-1234'
Phony.format('43198110', :format => :international, :spaces => :-).should == '+43-1-98110'
Phony.format('43198110', :format => :international_absolute, :spaces => :-).should == '+43-1-98110'
Phony.format('33142278186', :format => :+, :spaces => :-).should == '+33-1-42-27-81-86'
Phony.format('43198110', :format => :international_relative, :spaces => :-).should == '0043-1-98110'
Phony.format('4233841148', :format => :international_relative, :spaces => :-).should == '00423-384-11-48'
Phony.format('41443643532', :format => :national).should == '044 364 35 32'
Phony.format('41800112233', :format => :national).should == '0800 11 22 33'
Phony.format('43198110', :format => :national).should == '01 98110'
Phony.format('41443643532', :format => :local).should == '364 35 32'
Phony.format('493038625454', :format => :local).should == '386 25454'
Phony.split('43198110').should == ['43', '1', '98110']
Phony.split('33112345678').should == ['33', '1', '12','34','56','78']
Phony.split('4976112345').should == ['49', '761', '123', '45']
Phony.split('3928061371').should == ['39', '2', '806', '1371']
Phony.split('41443643532').should == ['41', '44', '364', '35', '32']
Phony.split('15551115511').should == ['1', '555', '111', '5511']
Phony.split('6491234567').should == ['64', '9', '123', '4567']
Phony.split('41800334455').should == ['41', '800', '33', '44', '55']
Note: There is also a ! version of each of these methods which
will destroy the original string and return a new (or old) one.
Just work only with the returned value, and you will be fine.