本文目录导读:

在Python中校验手机号格式有多种方法,以下是几种常用的实现方式:
方法1:使用正则表达式(推荐)
import re
def validate_phone(phone):
"""
校验中国手机号格式
规则:1开头的11位数字
"""
# 更精确的匹配:1[3-9]开头的11位数字
pattern = r'^1[3-9]\d{9}$'
if re.match(pattern, phone):
return True
else:
return False
# 测试
phone_numbers = [
'13812345678', # 有效
'15812345678', # 有效
'10012345678', # 无效(第二位不是3-9)
'1381234567', # 无效(只有10位)
'138123456789', # 无效(12位)
'abcdefghijk', # 无效(包含字母)
]
for phone in phone_numbers:
print(f"{phone}: {'有效' if validate_phone(phone) else '无效'}")
方法2:使用纯字符串方法
def validate_phone_simple(phone):
"""
使用字符串方法校验
"""
# 检查是否为11位数字
if not phone.isdigit():
return False
if len(phone) != 11:
return False
# 检查是否以1开头
if phone[0] != '1':
return False
# 检查第二位是否为3-9
if phone[1] not in '3456789':
return False
return True
# 测试
print(validate_phone_simple('13812345678')) # True
print(validate_phone_simple('10012345678')) # False
方法3:更完整的校验(包含运营商判断)
import re
def validate_phone_complete(phone):
"""
完整的手机号校验,包含运营商判断
"""
# 去掉可能的空格和横线
phone = phone.strip().replace(' ', '').replace('-', '')
# 匹配规则
patterns = {
'中国移动': r'^1(3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478]|9[5])\d{8}$',
'中国联通': r'^1(3[0-2]|4[5]|5[56]|6[6]|7[1-6]|8[56])\d{8}$',
'中国电信': r'^1(3[3]|4[9]|5[3]|7[7]|8[019])\d{8}$',
'虚拟运营商': r'^1(7[0]|6[2]|9[0-9])\d{8}$'
}
for operator, pattern in patterns.items():
if re.match(pattern, phone):
return True, operator
return False, '无效手机号'
# 测试
test_numbers = [
'13800138000', # 移动
'18612345678', # 联通
'13312345678', # 电信
'17012345678', # 虚拟运营商
'10012345678', # 无效
]
for phone in test_numbers:
valid, operator = validate_phone_complete(phone)
print(f"{phone}: {operator if valid else '无效'}")
方法4:使用第三方库(phone或phonenumbers)
# 首先安装:pip install phonenumbers
import phonenumbers
from phonenumbers import carrier, timezone
def validate_phone_with_lib(phone):
"""
使用phonenumbers库校验(推荐用于生产环境)
"""
try:
# 解析电话号码,默认是中国
phone_number = phonenumbers.parse(phone, "CN")
if phonenumbers.is_valid_number(phone_number):
# 获取更多信息
carrier_name = carrier.name_for_number(phone_number, "zh")
timezone_info = timezone.time_zones_for_number(phone_number)
return {
'valid': True,
'carrier': carrier_name,
'timezone': timezone_info,
'type': 'mobile' if phonenumbers.number_type(phone_number) == phonenumbers.PhoneNumberType.MOBILE else 'other'
}
else:
return {'valid': False, 'error': '无效的手机号'}
except phonenumbers.phonenumberutil.NumberParseException as e:
return {'valid': False, 'error': str(e)}
# 测试
result = validate_phone_with_lib('13812345678')
print(result)
实际应用示例
import re
from typing import Tuple
class PhoneValidator:
"""手机号校验类"""
# 基础正则:1开头的11位数字
PHONE_PATTERN = r'^1\d{10}$'
# 更严格的正则:1[3-9]开头的11位数字
STRICT_PATTERN = r'^1[3-9]\d{9}$'
@staticmethod
def validate_input(phone: str) -> Tuple[bool, str]:
"""
输入验证,包含格式清理
"""
if not phone:
return False, '手机号不能为空'
# 清理输入
cleaned = phone.strip()
# 检查长度
if len(cleaned) != 11:
return False, f'手机号长度应为11位,当前为{len(cleaned)}位'
# 检查是否全为数字
if not cleaned.isdigit():
return False, '手机号只能包含数字'
# 检查第一位
if cleaned[0] != '1':
return False, '手机号必须以1开头'
return True, cleaned
@staticmethod
def validate_format(phone: str, strict: bool = True) -> Tuple[bool, str]:
"""
格式验证
"""
# 先进行输入验证
valid, result = PhoneValidator.validate_input(phone)
if not valid:
return False, result
# 正则匹配
pattern = PhoneValidator.STRICT_PATTERN if strict else PhoneValidator.PHONE_PATTERN
if re.match(pattern, result):
return True, '手机号格式正确'
else:
return False, '手机号格式不正确'
# 使用示例
def main():
validator = PhoneValidator()
test_cases = [
'13812345678', # 有效
'10012345678', # 无效(第二位不是3-9)
'13812345678abc', # 无效(包含字母)
'1381234567', # 无效(长度不够)
'', # 无效(空值)
None, # 无效(None)
]
for phone in test_cases:
valid, message = validator.validate_format(phone)
status = "✓" if valid else "✗"
print(f"{status} {phone}: {message}")
if __name__ == '__main__':
main()
最佳实践建议
- 简单场景:使用正则表达式(方法1)
- 生产环境:使用phonenumbers库(方法4)
- 需要运营商信息:使用方法3或方法4
- 注重性能:使用字符串方法(方法2)
注意事项:
- 手机号规则会随着运营商更新而变化,建议定期更新正则表达式
- 考虑国际号码时使用phonenumbers库
- 输入验证时清除空白字符和前导0等
这样可以满足大多数手机号格式校验的需求。