提取电话号码和重新格式化的更好方法?

Kev*_*ott 4 ruby refactoring

各种格式的电话号码数据(我之所以选择这些,是因为进来的数据不可靠而且不是预期的格式):

+1 480-874-4666
404-581-4000
(805) 682-4726
978-851-7321, Ext 2606
413- 658-1100
(513) 287-7000,Toll Free (800) 733-2077
1 (813) 274-8130
212-363-3200,Media Relations: 212-668-2251.
323/221-2164
Run Code Online (Sandbox Code Playgroud)

我的Ruby代码提取所有数字,删除美国国家代码的任何前导1,然后使用前10位数字以所需格式创建"新"电话号码:

  nums = phone_number_string.scan(/[0-9]+/)
  if nums.size > 0
    all_nums = nums.join
    all_nums = all_nums[0..0] == "1" ? all_nums[1..-1] : all_nums
    if all_nums.size >= 10
      ten_nums = all_nums[0..9]
      final_phone = "#{ten_nums[0..2]}-#{ten_nums[3..5]}-#{ten_nums[6..9]}"
    else
      final_phone = ""
    end
    puts "#{final_phone}"
  else
    puts "No number to fix."
  end
Run Code Online (Sandbox Code Playgroud)

结果非常好!

480-874-4666
404-581-4000
805-682-4726
978-851-7321
413-658-1100
513-287-7000
813-274-8130
212-363-3200
323-221-2164
Run Code Online (Sandbox Code Playgroud)

但是,我认为有更好的方法.你能否重构这个更有效,更清晰,更有用?

Rya*_*ary 14

这是一个更简单的方法,只使用正则表达式和替换:

def extract_phone_number(input)
  if input.gsub(/\D/, "").match(/^1?(\d{3})(\d{3})(\d{4})/)
    [$1, $2, $3].join("-")
  end
end
Run Code Online (Sandbox Code Playgroud)

这将删除所有非数字(\D),跳过可选的前导(^1?),然后以块((\d{3})(\d{3})(\d{4}))和格式提取剩余的第10个数字.

这是测试:

test_data = {
  "+1 480-874-4666"                             => "480-874-4666",
  "404-581-4000"                                => "404-581-4000",
  "(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",
  "1 (813) 274-8130"                            => "813-274-8130",
  "212-363-3200,Media Relations: 212-668-2251." => "212-363-3200",
  "323/221-2164"                                => "323-221-2164",
  ""                                            => nil,
  "foobar"                                      => nil,
  "1234567"                                     => nil,
}

test_data.each do |input, expected_output|
  extracted = extract_phone_number(input)
  print "FAIL (expected #{expected_output}): " unless extracted == expected_output
  puts extracted
end
Run Code Online (Sandbox Code Playgroud)