我试图把一个全面的正则表达式放在一起来验证电话号码。理想情况下,它可以处理国际格式,但它必须处理美国格式,包括以下内容:

1-234-567-8901 1-234-567-8901 x1234 1-234-567-8901 ext1234 1 (234) 567-8901 1.234.567.8901 1/234/567/8901 12345678901

我会用我目前的尝试来回答,但我希望有人有更好的和/或更优雅的东西。


当前回答

既然写电话号码有很多选择, 我们可以测试其中有足够的数字,不管它们是如何分开的。我发现9到14个数字适合我:

^\D*(\d\D*){9,14}$

正确的:

123456789 1234567890123 +123 (456) 78.90-98.76

错误的:

123 (1234) 1234 9007199254740991 我不会按你说的去做 +123 (456) 78.90-98.76 #543 ext 210>2>5>3 早上打456-7890 18:00后打987 - 54-3210找雪莉

如果你想支持最后两个例子,只需要移除上限:

(\d\D*){9,}

(如果没有上限,则不需要^$)

其他回答

你会很难用一个简单的正则表达式处理国际号码,看看这篇关于国际(甚至北美)电话号码的困难的文章。

您需要解析前几位数字以确定国家代码,然后根据国家采取不同的操作。

除此之外——你给出的列表不包括另一种常见的美国格式——省略了首字母1。在美国,大多数手机都不需要这种功能,这将开始困扰年轻一代,除非他们拨打国际长途电话。

你已经正确地认识到这是一个棘手的问题。

亚当

我不建议使用正则表达式。

和上面的答案一样,去掉所有难看的电话号码,这样你就只剩下一串数字字符,如果提供扩展名的话,还会有一个'x'。

在Python中:

注意:BAD_AREA_CODES来自一个文本文件,您可以从web上获取。

BAD_AREA_CODES = open('badareacodes.txt', 'r').read().split('\n')

def is_valid_phone(phone_number, country_code='US'):
    """for now, only US codes are handled"""
    if country_code:
        country_code = country_code.upper()

    #drop everything except 0-9 and 'x'
    phone_number = filter(lambda n: n.isdigit() or n == 'x', phone_number)

    ext = None
    check_ext = phone_number.split('x')
    if len(check_ext) > 1:
        #there's an extension. Check for errors.
        if len(check_ext) > 2:
            return False
        phone_number, ext = check_ext

    #we only accept 10 digit phone numbers.
    if len(phone_number) == 11 and phone_number[0] == '1':
        #international code
        phone_number = phone_number[1:]
    if len(phone_number) != 10:
        return False

    #area_code: XXXxxxxxxx 
    #head:      xxxXXXxxxx
    #tail:      xxxxxxXXXX
    area_code = phone_number[ :3]
    head      = phone_number[3:6]
    tail      = phone_number[6: ]

    if area_code in BAD_AREA_CODES:
        return False
    if head[0] == '1':
        return False
    if head[1:] == '11':
        return False

    #any other ideas?
    return True

这涵盖了相当多的内容。它不是一个正则表达式,但它确实很容易映射到其他语言。

    pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" 
    validateat="onsubmit"

必须以数字结尾,可以以(或+或数字开头,并且可以包含+ -(或)

简单的正则表达式和其他技巧都有用。

.*

但是显示输入的提示/示例/占位符/工具提示。

然后在提交之前在前端验证格式是否正确是最好的体验。

这将为没有经验的用户简化格式。

更好的选择……只要去掉输入中的所有非数字字符(除了“x”和前导的“+”符号),注意,因为英国人倾向于用非标准形式的+44(0)写数字……当要求使用国际前缀时(在这种特定情况下,应该完全丢弃(0))。

然后,你会得到这样的值:

 12345678901
 12345678901x1234
 345678901x1234
 12344678901
 12345678901
 12345678901
 12345678901
 +4112345678
 +441234567890

然后,当你显示,重新格式化为您的心脏内容。如。

  1 (234) 567-8901
  1 (234) 567-8901 x1234