纯ruby英国电话号码验证器



我正在尝试为英国的号码实现一个纯Ruby电话号码验证器。有很多与电话验证相关的主题,但其中大多数使用正则表达式,我想避免(主要是因为它是不可读的)。我知道phone_validator_gem,但坦率地说,我不想使用任何额外的gem。

让我们做这些假设:

  • 允许任何后缀格式(+447…, 447……, 07年……)
  • 英国的电话号码是11位长,当在07…格式,前缀后面总是有7(无论是+44,44还是0)

实现的模块应该做:

  • 删除编号
  • 中的空格
  • 检查是否有效(如果无效则抛出错误)
  • 以+447…

。我用071234 56789作为输入调用format,它应该返回+447123456789。如果我用063434来调用它,它应该会引发一个错误。

我不知道有没有办法避免正则表达式?到目前为止,我所做的只是简单地删除空白并检查它是否是11位数字。长,我的模块如下:

module Uk
VALID_PREFIX = '+447'
def self.format(number)
clear_format = number.delete(' ')
return clear_format if clear_format.delete('^0-9').length == 11 && clear_format[0, 4].includes?(VALID_PREFIX)
end
end

如果你想避免使用gem和正则表达式,那么你就是在硬模式下运行Rails。我强烈建议你花点时间来适应这两种环境。

解析电话号码总是比你想象的更复杂。例如,您假设"英国电话号码是11位数字长,而在07…格式和前缀后面总是有7(无论是+44,44还是0)"不正确。07只是一个很普通的前缀

最好把它留给别人的问题,所以如果有宝石就用它。例如,uk-phone-number-formatter似乎正是你想要的,它是微小的。


假设我们在没有正则表达式和gem的情况下这样做,并假设07是唯一的前缀。首先,把问题分成两步。

  1. 正常化
  2. <
  3. 验证/gh>

规范化是重新格式化电话号码,使相等的电话号码看起来相同。验证正在验证它是一个电话号码。如果数据已经被规范化,验证就容易得多。

这意味着去掉所有不是数字的内容,固定前缀,并在前面添加+

使用gsub:phone.gsub!(/D+/)很容易剥离所有非数字的内容。或者非正则表达式delete:phone.delete('^0-9')

现在把非数字排除在外,我们只想改变"07"进入"447"。

最后,添加+.

def normalize(phone)
# Strip non-digits.
normalized = phone.delete('^0-9')
# Replace 07x with 447x  
if normalized[0..1] == "07"
normalized[0] = "44"
end
# Add the plus.
return "+#{normalized}"
end

现在规范化了,验证就很容易了。

# We assume the phone number is validated.
def phone_is_uk_format(phone)
errors.add(:phone, :missing_prefx, message: "Missing +447 prefix")
if normalized[0..3] != "+447"
# 12 because of the leading +
errors.add(:phone, :wrong_length, message: "A phone number is 11 digits")
if normalized.length != 12
end

并将其与模型集成…

class Person < ApplicationRecord
validate :phone_is_uk_format
# Normalize the phone number when it is set.
def phone=(number)
super(normalize_uk_phone(number))
end
private def phone_is_uk_format
# Validating presence is different.
return if phone.blank?
errors.add(:phone, :missing_prefx, message: "Missing +447 prefix")
if phone[0..3] != "+447"
# 12 because of the leading +
errors.add(:phone, :wrong_length, message: "A phone number is 11 digits")
if phone.length != 12
end
private def normalize_uk_phone(phone)
# Strip non-digits.
normalized = phone.delete('^0-9')
# Replace 07x with 447x  
if normalized[0..1] == "07"
normalized[0] = "44"
end
# Add the plus.
return "+#{normalized}"
end
end

最新更新