Python案例如何校验手机号格式?

wen python案例 19

本文目录导读:

Python案例如何校验手机号格式?

  1. 方法1:使用正则表达式(推荐)
  2. 方法2:使用纯字符串方法
  3. 方法3:更完整的校验(包含运营商判断)
  4. 方法4:使用第三方库(phone或phonenumbers)
  5. 实际应用示例
  6. 最佳实践建议

在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. 简单场景:使用正则表达式(方法1)
  2. 生产环境:使用phonenumbers库(方法4)
  3. 需要运营商信息:使用方法3或方法4
  4. 注重性能:使用字符串方法(方法2)

注意事项

  • 手机号规则会随着运营商更新而变化,建议定期更新正则表达式
  • 考虑国际号码时使用phonenumbers库
  • 输入验证时清除空白字符和前导0等

这样可以满足大多数手机号格式校验的需求。

抱歉,评论功能暂时关闭!