【问题标题】:Regular expression to match standard 10 digit phone number匹配标准 10 位电话号码的正则表达式
【发布时间】:2013-05-17 22:22:24
【问题描述】:

我想为支持以下格式的标准美式电话号码编写正则表达式:

###-###-####
(###) ###-####
### ### ####
###.###.####

其中 # 表示任意数字。到目前为止,我想出了以下表达式

^[1-9]\d{2}-\d{3}-\d{4}
^\(\d{3}\)\s\d{3}-\d{4}
^[1-9]\d{2}\s\d{3}\s\d{4}
^[1-9]\d{2}\.\d{3}\.\d{4}

分别。我不太确定最后一个对于虚线检查是否正确。我还想知道是否有任何方法可以编写一个表达式,而不是 4 个不同的表达式来满足我提到的不同格式。如果是这样,我不确定我该怎么做。以及如何修改表达式/表达式,以便我还可以包含一个条件来支持区号作为可选组件。类似的东西

+1 ### ### ####

其中+1是区号,是可选的。

【问题讨论】:

  • stackoverflow.com/questions/123559/… 的可能重复项建议的答案是去除每个非数字字符。通过这种方式,您可以简化验证
  • 我知道这是很久以前的事了,但我认为美国区号不能以 1 开头。(123) 456-7890 会因为前导 1 而无效。
  • 更完整的正确答案见:stackoverflow.com/a/18626090/561710
  • 解析电话号码很难。谷歌为此发布了一个开源库。帮助自己,使用libphonenumber(或您的语言的分支)

标签: regex


【解决方案1】:
^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$

符合以下条件

123-456-7890
(123) 456-7890
123 456 7890
123.456.7890
+91 (123) 456-7890

如果您不想匹配非美国号码,请使用

^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$

更新:
正如下面的用户 Simon Weaver 所注意到的,如果您也有兴趣匹配未格式化的数字,只需将分隔符类设为可选 [\s.-]?

^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$

【讨论】:

  • 您认为第一行的 (?\d{3}) 部分不需要问号吗?我认为我们确实需要出现一次或多次,而不是在“(”和“)”中出现零或一次数字
  • ? 应用于括号 (),而不是数字。完整的相关正则表达式是\(?\d{3}\)?\d{3} 指定在() 之间必须有三个数字,这些数字是(由? 制作的)可选的。
  • 注意:这与 1234567890 不匹配,这可能是也可能不是问题。对我来说是 - 所以我只是在每个 [\s.-] 之后添加了 ? 以使其成为可选
  • @Simon_Weaver 感谢您的意见。我已将您的观察添加到答案中。
  • 如果您想要避免@BobRay 提到的问题,请使用^(\+\d{1,2}\s)?((\(\d{3}\))|(\d{3}))[\s.-]\d{3}[\s.-]\d{4}$。 (我基本上只是复制了覆盖区号的 RegEx 段,并允许一个带括号的变体和一个不带括号的变体)
【解决方案2】:

这个问题有很多变体。这是一个类似于我之前放在 SO 上的答案的正则表达式。

^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$

它将匹配以下示例以及更多内容:

18005551234
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
800 555 1234x5678
8005551234 x5678
1    800    555-1234
1----800----555-1234

无论输入电话号码的方式如何,捕获组都可用于细分电话号码,以便您可以在代码中对其进行处理。

  • Group1:国家代码(例如:1 或 86)
  • Group2:区号(例如:800)
  • Group3:交换(例如:555)
  • Group4:订户号码(例如:1234)
  • Group5:分机(例如:5678)

如果您有兴趣,这里是表达式的细分:

^\s*                #Line start, match any whitespaces at the beginning if any.
(?:\+?(\d{1,3}))?   #GROUP 1: The country code. Optional.
[-. (]*             #Allow certain non numeric characters that may appear between the Country Code and the Area Code.
(\d{3})             #GROUP 2: The Area Code. Required.
[-. )]*             #Allow certain non numeric characters that may appear between the Area Code and the Exchange number.
(\d{3})             #GROUP 3: The Exchange number. Required.
[-. ]*              #Allow certain non numeric characters that may appear between the Exchange number and the Subscriber number.
(\d{4})             #Group 4: The Subscriber Number. Required.
(?: *x(\d+))?       #Group 5: The Extension number. Optional.
\s*$                #Match any ending whitespaces if any and the end of string.

要使区号可选,只需在区号 (\d{3}) 后添加一个问号即可。

【讨论】:

  • 最佳答案恕我直言。对于我的目的,开头和结尾的\s 是不需要的,因为我正在使用验证,并且该字段已被修剪。
  • 迄今为止最好的答案和最完整的。我也非常感谢正则表达式的分解。
  • @Kondal 我很好奇您用来使其失败的输入。国家代码为 0 对我来说似乎很好用。
  • @Kondal 对不起。我的意思是您尝试匹配的文本在此正则表达式中失败。
【解决方案3】:

^(\+\d{1,2}\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$

匹配这些电话号码:

1-718-444-1122
718-444-1122
(718)-444-1122
17184441122
7184441122
718.444.1122
1718.444.1122
1-123-456-7890
1 123-456-7890
1 (123) 456-7890
1 123 456 7890
1.123.456.7890
+91 (123) 456-7890
18005551234
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
18001234567
1 800 123 4567
1-800-123-4567
+18001234567
+1 800 123 4567
+1 (800) 123 4567
1(800)1234567
+1800 1234567
1.8001234567
1.800.123.4567
+1 (800) 123-4567
18001234567
1 800 123 4567
+1 800 123-4567
+86 800 123 4567
1-800-123-4567
1 (800) 123-4567
(800)123-4567
(800) 123-4567
(800)1234567
800-123-4567
800.123.4567
1231231231
123-1231231
123123-1231
123-123 1231
123 123-1231
123-123-1231
(123)123-1231
(123)123 1231
(123) 123-1231
(123) 123 1231
+99 1234567890
+991234567890
(555) 444-6789
555-444-6789
555.444.6789
555 444 6789
18005551234
1 800 555 1234
+1 800 555-1234
+86 800 555 1234
1-800-555-1234
1.800.555.1234
+1.800.555.1234
1 (800) 555-1234
(800)555-1234
(800) 555-1234
(800)5551234
800-555-1234
800.555.1234
(003) 555-1212
(103) 555-1212
(911) 555-1212
18005551234
1 800 555 1234
+86 800-555-1234
1 (800) 555-1234

regex101.com

【讨论】:

  • 稍作修改,也支持不加区号的本地电话号码:((\+\d{1,2}\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?)?\d{3}[\s.-]?\d{4}
【解决方案4】:

这是我创建的一个相当紧凑的。

Search: \+?1?\s*\(?-*\.*(\d{3})\)?\.*-*\s*(\d{3})\.*-*\s*(\d{4})$

Replace: +1 \($1\) $2-$3

针对以下用例进行了测试。

18001234567
1 800 123 4567
1-800-123-4567
+18001234567
+1 800 123 4567
+1 (800) 123 4567
1(800)1234567
+1800 1234567
1.8001234567
1.800.123.4567
1--800--123--4567
+1 (800) 123-4567

【讨论】:

  • 这匹配诸如 (800 444-4444) 之类的内容
【解决方案5】:

用于验证常规 10 位电话号码加上 可选国际代码(1 到 3 位)和 可选分机号码(任何位数):

/(\+\d{1,3}\s?)?((\(\d{3}\)\s?)|(\d{3})(\s|-?))(\d{3}(\s|-?))(\d{4})(\s?(([E|e]xt[:|.|]?)|x|X)(\s?\d+))?/g

演示:https://www.regextester.com/103299

有效条目:

/* Full number */
+999 (999) 999-9999 Ext. 99999

/* Regular local phone number (XXX) XXX-XXXX */
1231231231
123-1231231
123123-1231
123-123 1231
123 123-1231
123-123-1231
(123)123-1231
(123)123 1231
(123) 123-1231
(123) 123 1231

/* International codes +XXX (XXX) XXX-XXXX */
+99 1234567890
+991234567890

/* Extensions (XXX) XXX-XXXX Ext. XXX... */
1234567890 Ext 1123123
1234567890Ext 1123123
1234567890 Ext1123123
1234567890Ext1123123

1234567890 Ext: 1123123
1234567890Ext: 1123123
1234567890 Ext:1123123
1234567890Ext:1123123

1234567890 Ext. 1123123
1234567890Ext. 1123123
1234567890 Ext.1123123
1234567890Ext.1123123

1234567890 ext 1123123
1234567890ext 1123123
1234567890 ext1123123
1234567890ext1123123

1234567890 ext: 1123123
1234567890ext: 1123123
1234567890 ext:1123123
1234567890ext:1123123

1234567890 X 1123123
1234567890X1123123
1234567890X 1123123
1234567890 X1123123
1234567890 x 1123123
1234567890x1123123
1234567890 x1123123
1234567890x 1123123

【讨论】:

    【解决方案6】:

    在 jsfiddle 上使用上述解决方案添加一个示例。 我根据客户的要求对代码进行了一些修改。希望这也对某人有所帮助。

    /^\s*(?:\+?(\d{1,3}))?[- (]*(\d{3})[- )]*(\d{3})[- ]*(\d{4})(?: *[x/#]{1}(\d+))?\s*$/
    

    See Example Here

    【讨论】:

      【解决方案7】:

      为巴基斯坦用户试试这个。这是我创建的一个相当紧凑的。

      ((\+92)|0)[.\- ]?[0-9][.\- ]?[0-9][.\- ]?[0-9]
      

      针对以下用例进行了测试。

      +92 -345 -123 -4567
      +92 333 123 4567
      +92 300 123 4567
      +92 321 123 -4567
      +92 345 - 540 - 5883
      

      【讨论】:

      • 你好 Sajjid。如果我想添加 03041234567。什么是正则表达式。
      【解决方案8】:

      我使用的电话号码正则表达式: /^[+]?(\d{1,2})?[\s.-]?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/

      封面:

      • 18001234567
      • 1 800 123 4567
      • +1 800 123-4567
      • +86 800 123 4567
      • 1-800-123-4567
      • 1 (800) 123-4567
      • (800)123-4567
      • (800) 123-4567
      • (800)1234567
      • 800-123-4567
      • 800.123.4567

      【讨论】:

        【解决方案9】:

        从@Ravi 的回答开始,我也申请了一些validation rules for the NPA (Area) Code

        特别是:

        • 应该以 2(或更高)开头
        • 第二位和第三位数字 (N11) 不能为“11”。

        还有一些其他限制,包括保留块(N9X、37X、96X)和 555,但我没有考虑这些限制,特别是因为保留块可能会在未来被使用,而 555 对测试很有用。

        这是我想出的:

        ^((\+\d{1,2}|1)[\s.-]?)?\(?[2-9](?!11)\d{2}\)?[\s.-]?\d{3}[\s.-]?\d{4}$
        

        或者,如果您还想匹配空白值(如果该字段不是必需的),您可以使用:

        (^((\+\d{1,2}|1)[\s.-]?)?\(?[2-9](?!11)\d{2}\)?[\s.-]?\d{3}[\s.-]?\d{4}$|^$)
        

        我对有效数字的测试用例(很多来自@Francis 的回答)是:

        18005551234
        1 800 555 1234
        +1 800 555-1234
        +86 800 555 1234
        1-800-555-1234
        1.800.555.1234
        +1.800.555.1234
        1 (800) 555-1234
        (800)555-1234
        (800) 555-1234
        (800)5551234
        800-555-1234
        800.555.1234
        

        我的无效测试用例包括:

        (003) 555-1212     // Area code starts with 0
        (103) 555-1212     // Area code starts with 1
        (911) 555-1212     // Area code ends with 11
        180055512345       // Too many digits
        1 800 5555 1234    // Prefix code too long
        +1 800 555x1234    // Invalid delimiter
        +867 800 555 1234  // Country code too long
        1-800-555-1234p    // Invalid character
        1 (800)  555-1234  // Too many spaces
        800x555x1234       // Invalid delimiter
        86 800 555 1212    // Non-NA country code doesn't have +
        

        我的正则表达式不包括用于提取数字组的分组,但可以对其进行修改以包含这些。

        【讨论】:

        • 很好的答案+添加。谢谢
        【解决方案10】:

        1、3、4的表达方式很相似,可以使用:

        ^([1-9]\d{2})([- .])(\d{3})$2(\d{4})$
        

        请注意,根据所使用的正则表达式的语言和品牌,您可能需要使用\2 而不是$2,否则可能根本不支持此类匹配。

        除了明显的 ^(regex for 1,3,4|regex for 2)$ 丑陋、笨拙并且很难找出数字的各个部分之外,我认为没有什么好的方法可以将它与格式 2 结合起来。

        至于区号,可以在开头加(\+\d)?,捕获一个个位数的区号(对不起,我不知道你们区号的格式)。

        【讨论】:

          【解决方案11】:

          这个怎么样?

          ^(\+?[01])?[-.\s]?\(?[1-9]\d{2}\)?[-.\s]?\d{3}[-.\s]?\d{4}
          

          编辑:我忘记了 () 之一。 编辑 2:前 3 位数字部分错误。

          【讨论】:

          • 在字符类中不需要转义点.,所以[-\.\s]实际上应该是[-.\s],因为我们不想匹配反斜杠。
          • 它真的会匹配反斜杠吗?我认为这可能没有必要,但我不是 100% 确定。
          • 你是对的。我刚刚尝试过(我以前从不需要反斜杠),[\.][.] 都只匹配点,而[\\.] 匹配点和反斜杠。谢谢你的评论。
          • 我对正则表达式的看法是,如果您将正则表达式提供给某人,请始终附上解释,否则正则表达式毫无价值。只是我的意见。
          【解决方案12】:

          与其他几个相比,可能是最简单的一个。

          \(?\d+\)?[-.\s]?\d+[-.\s]?\d+
          

          符合以下条件:

          (555) 444-6789

          555-444-6789

          555.444.6789

          555 444 6789

          【讨论】:

          • 完美的...谢谢(y)
          【解决方案13】:

          此代码将与美国或加拿大的电话号码匹配,并且还将确保它是有效的区号和交换:

          ^((\+1)?[\s-]?)?\(?[2-9]\d\d\)?[\s-]?[2-9]\d\d[\s-]?\d\d\d\d
          

          Test on Regex101.com

          【讨论】:

            【解决方案14】:

            我发现这个正则表达式对我来说最有用的 10 位联系号码:

            ^(?:(?:\+|0{0,2})91(\s*[\-]\s*)?|[0]?)?[789]\d{9}$
            

            参考https://regex101.com/r/QeQewP/1

            说明:

            【讨论】:

            • 您是否使用工具来生成该解释?分享!谢谢
            • @unnknown 看起来像来自在线正则表达式检查器的屏幕截图,例如 regex101.com。请注意,SO 指南规定所有文本、代码、数据和错误消息都必须以文本形式输入,而不是图像,因为图像中的文本可能难以阅读,尤其是在移动设备上,并且会占用更大的带宽。文本也不能复制粘贴。在这种情况下,颜色可能会增加一些东西,不确定。要知道,一般来说,“答案”应该包括文字解释。 Amitesh:包含一个指向该站点的链接会很有用,您的正则表达式已经填充好供访问者试验。
            • @unnknown 这里是一个链接,它生成的图像与本文中的图像相似。 Amitesh 的正则表达式字符串已经被粘贴进去了,你可以输入电话号码来测试它的结果:regex101.com/r/QeQewP/1
            【解决方案15】:

            上面的正则表达式是对的轻微修改@Francis Gagnon.

            目标:检测用户可以分享其美国电话号码的任何可能模式


            版本 1:

            ^\s*(?:\+?(\d{1,3}))?[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d)[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d)[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d[\W\D\s]*?\d)(?: *x(\d+))?\s*$
            

            在这里测试它 Codepen:https://codepen.io/kiranbhattarai/pen/NWKMXQO

            正则表达式解释:https://regexr.com/4kt5j


            第 2 版:

            \s*(?:\+?(\d{1,3}))?[\W\D\s]^|()*(\d[\W\D\s]*?\d[\D\W\s]*?\d)[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d)[\W\D\s]*(\d[\W\D\s]*?\d[\D\W\s]*?\d[\W\D\s]*?\d)(?: *x(\d+))?\s*$
            

            里面有什么:测试用例可以是字符串的一部分。在第一版中,测试用例应该是工作的开始。

            Codepen:https://codepen.io/kiranbhattarai/pen/GRKGNGG

            正则表达式解释:https://regexr.com/4kt9n


            如果你能找到可能失败的模式,请发表评论,我会修复它。

            测试用例:通过

            8 0   0  4  4  4  5   55 5
            1 800 555 1234
            +1 800 555-1234
            +86 800 555 1234
            1-800-555-1234
            1 (800) 555-1234
            (800)555-1234
            (800) 555-1234
            (800)5551234
            800-555-1234
            800.555.1234
            800 555 1234x5678
            8005551234 x5678
            1    800    555-1234
            1----800----555-1234
            800 (555) 1234
            800(555)1234
            8 0 0 5 5 5 1 2 3 4
            8.0.0.5.5.5.1.2.3.4
            8-0-0-5-5-5-1-2-3-4
            (8)005551234
            (80)05551234
            8(00)5551234
            8@0@0@5551234
            8/0/0/5/5/5/1/2/3/4
            8*0*0*5*5*5*1*2*3*4
            8:0:0:5:5:5:1:2:3:4
            8,0,0,5,5,5,1,2,3,4
            800,555,1234
            800:555:1234
            1-718-444-1122
            718-444-1122
            (718)-444-1122
            17184441122
            7184441122
            718.444.1122
            1718.444.1122
            1-123-456-7890
            1 123-456-7890
            1 (123) 456-7890
            1 123 456 7890
            1.123.456.7890
            +91 (123) 456-7890
            18005551234
            1 800 555 1234
            +1 800 555-1234
            +86 800 555 1234
            1-800-555-1234
            1 (800) 555-1234
            (800)555-1234
            (800) 555-1234
            (800)5551234
            800-555-1234
            800.555.1234
            18001234567
            1 800 123 4567
            1-800-123-4567
            +18001234567
            +1 800 123 4567
            +1 (800) 123 4567
            1(800)1234567
            +1800 1234567
            1.8001234567
            1.800.123.4567
            +1 (800) 123-4567
            18001234567
            1 800 123 4567
            +1 800 123-4567
            +86 800 123 4567
            1-800-123-4567
            1 (800) 123-4567
            (800)123-4567
            (800) 123-4567
            (800)1234567
            800-123-4567
            800.123.4567
            1231231231
            123-1231231
            123123-1231
            123-123 1231
            123 123-1231
            123-123-1231
            (123)123-1231
            (123) 123-1231
            (123) 123 1231
            +99 1234567890
            +991234567890
            (555) 444-6789
            555-444-6789
            555.444.6789
            555 444 6789
            1 800 555 1234
            +1 800 555-1234
            +86 800 555 1234
            1-800-555-1234
            1.800.555.1234
            +1.800.555.1234
            1 (800) 555-1234
            (800)555-1234
            (800) 555-1234
            (800)5551234
            800-555-1234
            800.555.1234
            (003) 555-1212
            (103) 555-1212
            (911) 555-1212
            18005551234
            1 800 555 1234
            +86 800-555-1234
            1 (800) 555-1234
            

            【讨论】:

            • +86、+99 等绝对不是美国电话号码。由于其他原因,您的其他几个测试用例看起来很可疑。
            • @tripleee 让我解决这个问题,我已经将它更新到任何我希望它有效的国家。此外,我还删除了重复的测试用例
            【解决方案16】:

            我只是把这个答案扔在那里,因为它解决了我的一个问题,它基于@stormy 的答案,但包括 3 位国家代码,更重要的是可以在字符串中的任何位置使用,但不会匹配是不是前面没有空格/字符串的开头并以单词边界结尾。这很有用,因此它不会匹配 URL 中间的随机数或其他东西

            ((?:\s|^)(?:\+\d{1,3}\s?)?1?\-?\.?\s?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4})(?:\b)
            

            【讨论】:

              【解决方案17】:
              ^(\+1)?\s?(\([1-9]\d{2}\)|[1-9]\d{2})(-|\s|.)\d{3}(-|\s|.)\d{4}
              

              【讨论】:

                【解决方案18】:

                这是一个更全面的版本,它将尽可能多地匹配,并为您提供国家、地区、第一个和最后一个的组匹配。

                (?<number>(\+?(?<country>(\d{1,3}))(\s|-|\.)?)?(\(?(?<region>(\d{3}))\)?(\s|-|\.)?)((?<first>(\d{3}))(\s|-|\.)?)((?<last>(\d{4}))))
                

                【讨论】:

                  【解决方案19】:

                  多个数字用“+”隔开"、"-" 或 " " 字符?

                  【讨论】:

                    【解决方案20】:

                    我最终得到了

                    const regexBase = '(?:\\+?(\\d{1,3}))?[-. (]*(\\d{3})?[-. )]*(\\d{3})[-. ]*(\\d{4,5})(?: *x(\\d+))?'; const phoneRegex = new RegExp('\\s*' + regexBase + '\\s*', 'g');

                    这是为了允许诸如荷兰数字之类的东西,例如

                    +358 300 20200

                    【讨论】:

                      猜你喜欢
                      • 2010-12-16
                      • 2020-01-18
                      • 1970-01-01
                      • 1970-01-01
                      • 2022-01-03
                      • 1970-01-01
                      • 1970-01-01
                      • 2013-04-14
                      • 1970-01-01
                      相关资源
                      最近更新 更多