Python-返回前验证电话号码
考虑到我使用的数据源非常脏,在“电话号码”字段中可能包含以下内容:Python-返回前验证电话号码,python,regex,Python,Regex,考虑到我使用的数据源非常脏,在“电话号码”字段中可能包含以下内容: 空(新标准) !!关闭 没有 我正在做一个大批量导入,我想确定的是,我甚至不必为这些东西操心。所以我在过滤一个类来格式化数字,但是我也想验证,如果不是数字,就把它扔掉 class PhoneNumber: def __init__( self, number_raw ): number = re.sub('[^0-9]', '', number_raw)
- 空(新标准)
- !!关闭李>
- 没有
class PhoneNumber:
def __init__( self, number_raw ):
number = re.sub('[^0-9]', '', number_raw)
self.area_code= number[ 0:3 ]
self.exchange = number[ 3:6 ]
self.line = number[ 6:13 ]
def __str__( self ):
return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
需要考虑的几件事:
- 我无法修改实际的数据源
- 在到达该类之前,我无法验证
False
,但我觉得这可能太草率了
有什么更好的方法来验证输入的仅仅是数字,如果输入的是字符串,则将其抛出&返回None
潜在解决方案1:
class PhoneNumber:
def __init__( self, number_raw ):
validation = re.match('[^0-9]', '', number_raw)
if validation is False:
return None
else:
number = re.sub('[^0-9]', '', number_raw)
self.area_code= number[ 0:3 ]
self.exchange = number[ 3:6 ]
self.line = number[ 6:13 ]
self.full_number = number
def __str__( self ):
return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
class PhoneNumber:
def __init__( self, number_raw ):
number = re.sub('[^0-9]', '', number_raw)
self.area_code = number[ 0:3 ]
self.exchange = number[ 3:6 ]
self.line = number[ 6:13 ]
self.og_number = number_raw
def __str__( self ):
validation = re.match('[^0-9]', '', self.og_number)
if validation is False:
return None
return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
class PhoneNumber:
def __init__( self, number_raw ):
self.area_code = number[0:3]
self.exchange = number[3:6]
self.line = number[6:13]
@classmethod
def is_number_valid(cls, number_raw):
try:
int(number_raw)
except ValueError:
return False
return True
def __new__(cls, number_raw):
if cls.is_number_valid(number_raw):
return super().__new__(cls)
潜在解决方案2:
class PhoneNumber:
def __init__( self, number_raw ):
validation = re.match('[^0-9]', '', number_raw)
if validation is False:
return None
else:
number = re.sub('[^0-9]', '', number_raw)
self.area_code= number[ 0:3 ]
self.exchange = number[ 3:6 ]
self.line = number[ 6:13 ]
self.full_number = number
def __str__( self ):
return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
class PhoneNumber:
def __init__( self, number_raw ):
number = re.sub('[^0-9]', '', number_raw)
self.area_code = number[ 0:3 ]
self.exchange = number[ 3:6 ]
self.line = number[ 6:13 ]
self.og_number = number_raw
def __str__( self ):
validation = re.match('[^0-9]', '', self.og_number)
if validation is False:
return None
return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
class PhoneNumber:
def __init__( self, number_raw ):
self.area_code = number[0:3]
self.exchange = number[3:6]
self.line = number[6:13]
@classmethod
def is_number_valid(cls, number_raw):
try:
int(number_raw)
except ValueError:
return False
return True
def __new__(cls, number_raw):
if cls.is_number_valid(number_raw):
return super().__new__(cls)
没有理由实例化所有字段都设置为“无”的对象。 我会对
\uuuu init\uuuu
进行一些检查,如下所示:
class PhoneNumber:
def __init__(self, number_raw):
number = int(number_raw) # do not catch exception here, catch it on instantiation
number_str = str(number) # parse to str for slicing
self.areaCode = number_str[0:3] # note no space around slicing indexes
self.exchange = number_str[3:6]
self.line = number_str[6:13]
另外,值得注意的是使用类似PEP-8的变量,所以使用
area\u code
而不是areaCode
第二种方法(使用classmethod)
如果出于某些原因需要返回None
,您可能会发现使用classmethod进行实例化非常有用,如下所示:
class PhoneNumber:
def __init__(self, number_raw):
self.areaCode = number_raw[0:3]
self.exchange = number_raw[3:6]
self.line = number_raw[6:13]
@classmethod
def instantiate_with_checks(cls, number_raw):
try:
int(number_raw)
except ValueError:
return None
# after ensuring that provided variable is valid
return cls(number_raw)
实例化新的PhoneNumber
对象,如下所示:
PhoneNumber。使用\u检查(数字\u原始)实例化\u
第三种方式(使用\uuuu new\uuu
):
class PhoneNumber:
def __init__( self, number_raw ):
validation = re.match('[^0-9]', '', number_raw)
if validation is False:
return None
else:
number = re.sub('[^0-9]', '', number_raw)
self.area_code= number[ 0:3 ]
self.exchange = number[ 3:6 ]
self.line = number[ 6:13 ]
self.full_number = number
def __str__( self ):
return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
class PhoneNumber:
def __init__( self, number_raw ):
number = re.sub('[^0-9]', '', number_raw)
self.area_code = number[ 0:3 ]
self.exchange = number[ 3:6 ]
self.line = number[ 6:13 ]
self.og_number = number_raw
def __str__( self ):
validation = re.match('[^0-9]', '', self.og_number)
if validation is False:
return None
return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
class PhoneNumber:
def __init__( self, number_raw ):
self.area_code = number[0:3]
self.exchange = number[3:6]
self.line = number[6:13]
@classmethod
def is_number_valid(cls, number_raw):
try:
int(number_raw)
except ValueError:
return False
return True
def __new__(cls, number_raw):
if cls.is_number_valid(number_raw):
return super().__new__(cls)
也许只需在init中进行格式化,然后在那里决定您是否拥有有效的数字
class FormattedPhoneNumber(object):
def __init__(self, number):
try:
as_number = int(number)
except (TypeError, ValueError):
self._formatted = None
else:
# you have a number, do whatever formatting you need to do
area_code = number[ 0:3 ]
exchange = number[ 3:6 ]
line = number[ 6:13 ]
self._formatted = "({0}) {1}-{2}".format(area_code,exchange,line)
def __str__(self):
return self._formatted
当你说你想“扔掉它”时,你是想对结果数字使用None,还是想跳过整个记录?如果手机与模式不匹配,可能会在
\uuuuuuuu init\uuuuuuu
上引发异常。然后简单地在电话号码
实例化中捕捉它。你能试着将它转换为int吗?在上捕捉它将是一个错误。如果无效,是否要将每个字段设置为None
(areaCode
,exchange
,行
)?请不要这样做。如果无效,则没有理由实例化的PhoneNumber
。我会坚持我的第一条评论。@Codespend添加了一个答案,你可以看一下。你介意在我的编辑中看一看我的潜在解决方案吗&与你的策略相比,这似乎更有效&为什么?你在那里实例化无用的对象。在\uuuu init\uuuu
中返回None
根本不起任何作用,事实上这是一种默认行为。关于PEP8,另一件需要提及的事情是,空格不会直接放在括号之后或之前。是的,这是有意义的,但是如果我理解正确,并且电话号码
是电话号码
类的实例化,那么电话号码将永远不会是无
。您可以使用\u新的
方法或类方法
来实现这一点。我将很快更新我的答案。也许用int(number)
而不是作为\u number=int(number)
会更好?Int版本是不必要的。