My approach is slightly different (and I think itโs better IMHO :-): I did not need to miss a single phone number, even if there were 2 on the line. I also did not want to receive lines with three sets of numbers that were far from each other (see A cookie example), and I didnโt want to mistakenly accept the IP address as a phone number.
Code to allow multiple numbers per line, but also requires the numbers of digits to be โcloseโ to each other:
def extract_phone_number(input) result = input.scan(/(\d{3})\D{0,3}(\d{3})\D{0,3}(\d{4})/).map{|e| e.join('-')}
And here are the tests (with a few extra tests)
test_data = { "DB=Sequel('postgres://user: username@192.168.1.101 /test_test')" => nil, # DON'T MISTAKE IP ADDRESSES AS PHONE NUMBERS "100 cookies + 950 cookes = 1050 cookies" => nil, # THIS IS NEW "this 123 is a 456 bad number 7890" => nil, # THIS IS NEW "212-363-3200,Media Relations: 212-668-2251." => "212-363-3200 :: 212-668-2251", # THIS IS CHANGED "this is +1 480-874-4666" => "480-874-4666", "something 404-581-4000" => "404-581-4000", "other (805) 682-4726" => "805-682-4726", "978-851-7321, Ext 2606" => "978-851-7321", "413- 658-1100" => "413-658-1100", "(513) 287-7000,Toll Free (800) 733-2077" => "513-287-7000 :: 800-733-2077", # THIS IS CHANGED "1 (813) 274-8130" => "813-274-8130", "323/221-2164" => "323-221-2164", "" => nil, "foobar" => nil, "1234567" => nil, } def test_it(test_data) test_data.each do |input, expected_output| extracted = extract_phone_number(input) puts "#{extracted == expected_output ? 'good': 'BAD!'} ::#{input} => #{extracted.inspect}" end end test_it(test_data)
Alternative implementation: using "scanning", it will automatically apply the regular expression several times, which is good if you want to add more than 1 phone number per line. If you just want to get the first phone number on the line, you can also use:
first_phone_number = begin m = /(\d{3})\D{0,3}(\d{3})\D{0,3}(\d{4})/.match(input) [m[1],m[2],m[3]].join('-') rescue nil; end
(just another way of doing things using the RegExp match function)