国际电话号码验证

5 投票
2 回答
13815 浏览
提问于 2025-04-17 07:50

我需要在Python中对所有美国和国际的电话号码进行一些基本的验证和格式化。以下是我目前的代码:

import re 

def validate(number):
    number = re.compile(r'[^0-9]').sub('', number)
    if len(number) == 10:
        # ten-digit number, great
        return number
    elif len(number) == 7:
        # 7-digit number, should include area code
        raise ValidationError("INCLUDE YOUR AREA CODE OR ELSE.")
    else:
        # I have no clue what to do here

def format(number):
    if len(number) == 10:
        # basically return XXX-XXX-XXXX
        return re.compile(r'^(\d{3})(\d{3})(\d{4})$').sub('$1-$2-$3', number)
    else:
        # basically return +XXX-XXX-XXX-XXXX
        return re.compile(r'^(\d+)(\d{3})(\d{3})(\d{4})$').sub('+$1-$2-$3-$4', number)

我最大的问题是,我对国际电话号码的工作原理完全不了解。我猜它们只是前面加上一个国家代码的10位数字。这是真的吗?

2 个回答

3

我不太在意格式,比如说空格和破折号的位置。
不过这里是我用来验证数字的正则表达式函数:

  • 首先,号码应该以一个加号和一些数字开头,表示国家代码。
  • 然后,可以包含一组括号,里面有数字,表示区号,或者可以选择性地加一个0。
  • 最后,号码应该以一个数字结束。
  • 号码本身可以包含空格或破折号(但国家代码和区号里不能有):
def is_valid_phone(phone):
    return re.match(r'(\+[0-9]+\s*)?(\([0-9]+\))?[\s0-9\-]+[0-9]+', phone)
8

E.164号码可以有最多十五位数字,除了国家代码(通常是1到3位数字)之外,你不能指望它们会有某种特定的格式。实际上,很多国家的电话号码并不是那种XXX-XXX-XXXX的格式。根据我的理解,你有三个选择:

  1. 费尽心思地建立一个包含每个国家代码电话号码格式的数据库。然后定期检查每个国家的更新。(补充说明:看起来谷歌已经在做这件事,所以如果你信任他们和Python的移植者能保持libphonenumber的正确性和更新,并且不介意每次有变化时都升级这个库,那可能对你有帮助。)
  2. 去掉提供的电话号码中的所有分隔符,直接格式化成没有空格的样子:+12128675309
  3. 按照用户提供的格式来处理号码,而不是自己错误地重新格式化。

撰写回答