电话号码验证正则表达式

69

我正在使用这个模式来检查电话号码的有效性

^[0-9\-\+]{9,15}$
它适用于0771234567+0771234567,但我希望它也适用于077-1234567+077-1234567、+077-1-23-45-67和+077-123-45-6-7。在模式中应该改变什么?

1
你是否曾经找到了一个足够的解决方案? - Gent
如果你正在尝试这样做,那么你可能是错误的。电话号码长度不同,包括不同的国家代码,总体上比你想象的更奇怪。Python和Java都有可以上下文解析电话号码的库,你应该使用这些工具,而不是试图让正则表达式来完成这项工作。 - boatcoder
18个回答

42

2
这允许包括以下非法/无效的号码234-911-5678和314-159-2653和123-234-5678 - Joe Johnston
字母也通过 - tylik

27

输入图像描述这个解决方案实际上验证了数字和格式。例如:123-456-7890是一种有效的格式,但不是一个有效的美国号码,而其他答案则没有考虑到这一点。


如果您不想要扩展功能,请删除以下内容(包括括号):(?:\s*(?:#|x.?|ext.?|extension)\s*(\d+)\s*)? :)

编辑(附录)我需要它在客户端应用程序中,所以我进行了转换。对于Javascript开发人员,这就是它:

var myPhoneRegex = /(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]‌​)\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)([2-9]1[02-9]‌​|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})\s*(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+)\s*)?$/i;
if (myPhoneRegex.test(phoneVar)) {
    // Successful match
} else {
    // Match attempt failed
}

这允许使用或不使用扩展名,并且与.NET一起使用。

(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]‌​)\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)([2-9]1[02-9]‌​|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$

验证时考虑尾随空格。也许在使用.NET验证器和服务器端修剪时使用略有不同的正则表达式:

要验证是否有或没有尾随空格,请使用此略微不同的正则表达式:

(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]‌​)\s*)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)([2-9]1[02-9]‌​|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})\s*(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+)\s*)?$

所有有效号码:

1 800 5551212

800 555 1212

8005551212

18005551212

+1800 555 1212 extension65432

800 5551212 ext3333

无效号码:

234-911-5678

314-159-2653

123-234-5678


 

编辑:根据Felipe的评论,我已经更新了国际号码的相关信息。

根据这里这里关于有效全球电话号码的信息

当然,这只是第一道防线的测试。一个国际号码的普遍要素是它不超过15个字符。我没有写一个替换所有非数字并求和结果的函数,这应该为完整性而完成。此外,您可能注意到我没有将北美正则表达式与此结合使用。原因是这个国际正则表达式将匹配北美号码,但也接受已知的无效#,例如+1 234-911-5678。为了获得更准确的结果,您应该将它们分开。

暂停和其他拨号工具未提及,因此在E.164标准中无效。

\(?\+[0-9]{1,3}\)? ?-?[0-9]{1,3} ?-?[0-9]{3,5} ?-?[0-9]{4}( ?-?[0-9]{3})?

使用1-10个字母作为扩展名和1-6位数字扩展名:

\(?\+[0-9]{1,3}\)? ?-?[0-9]{1,3} ?-?[0-9]{3,5} ?-?[0-9]{4}( ?-?[0-9]{3})? ?(\w{1,10}\s?\d{1,6})?

有效的国际号码:该国名称仅供参考,不匹配。

+55 11 99999-5555 Brazil

+593 7 282-3889 Ecuador

(+44) 0848 9123 456 UK

+1 284 852 5500 BVI

+1 345 9490088 Grand Cayman

+32 2 702-9200 Belgium

+65 6511 9266 Asia Pacific

+86 21 2230 1000 Shanghai

+9124 4723300 India

+821012345678 South Korea

此外,您还可以拨打以下分机号码

+55 11 99999-5555 ramal 123 Brazil

+55 11 99999-5555 foo786544 Brazil

祝愉快!


为什么这个号码无效?+55 11 99999-5555 - Felipe
1
看起来我需要为巴西(国际)更新。我会处理并更新答案。干得好。 - Joe Johnston
巴西的有效电话号码格式:+55.19.99999-9999,19 4444-4444,(19)99999999。建议在主要语言中包括“分机”的翻译,例如葡萄牙语中的“ramal”,还有西班牙语、意大利语和日语等。或者,用户可以在最后一个数字后输入任意字符,然后再输入数字,例如:+55.19.99999-9999 ramal 123 或 +55.19.99999-9999 xpto 123。 - Felipe
在欧洲一些国家,拥有这样的电话号码是被接受的: - tsveti_iko
2
+31 6 11 11 11 11(荷兰)或者使用“00”代替“+”,因此如果您想要覆盖这些号码,可以使用扩展版本:/(?+?[0-9]{1,3})? ?-?[0-9]{1,3} ?-?[0-9]{2,5} ?-?[0-9]{2,5}( ?-?[0-9]{2,5})? ?(\w{1,10}\s?\d{1,6})?/。 - tsveti_iko
显示剩余6条评论

15

我有一个更通用的正则表达式,允许用户只输入数字、+-空格()。它尊重括号平衡,并且在符号后始终有一个数字。

^([+]?[\s0-9]+)?(\d{3}|[(]?[0-9]+[)])?([-]?[\s]?[0-9])+$

false, ""
false, "+48 504 203 260@@"
false, "+48.504.203.260"
false, "+55(123) 456-78-90-"
false, "+55(123) - 456-78-90"
false, "504.203.260"
false, " "
false, "-"
false, "()"
false, "() + ()"
false, "(21 7777"
false, "+48 (21)"
false, "+"
true , " 1"
true , "1"
true, "555-5555-555"
true, "+48 504 203 260"
true, "+48 (12) 504 203 260"
true, "+48 (12) 504-203-260"
true, "+48(12)504203260"
true, "+4812504203260"
true, "4812504203260

12

考虑:

^\+?[0-9]{3}-?[0-9]{6,12}$

该正则表达式只允许在开头使用+; 它需要3个数字, 接着是一个可选的破折号, 然后是6-12个数字。

请注意,原始正则表达式允许像70+12---12+92这样的"电话号码",比您想象中更自由。


问题已经修改以添加:

+077-1-23-45-67和+077-123-45-6-7

现在你可能需要使用支持选择的正则表达式系统:

^\+?[0-9]{3}-?([0-9]{7}|[0-9]-[0-9]{2}-[0-9]{2}-[0-9]{2}|[0-9]{3}-[0-9]{2}-[0-9]-[0-9])$

第一种选择是七位数字;第二种是1-23-45-67;第三种是123-45-6-7。所有这些都共享可选的加号+,后跟3个数字和可选的破折号-前缀。

下面的评论提到了另一种模式:

+077-12-34-567

不清楚通用的模式应该是什么 - 可能是由连字符分隔的一个或多个数字;前后有数字?

^\+?[0-9]{3}-?[0-9](-[0-9]+)+$

这将允许以'+077-'前缀开始,后跟任何数字和短横线交替的序列,每个短横线之间至少有一个数字,并且末尾没有短横线。


谢谢,但是这种格式怎么样:+077-12-34-567。我希望它是全球通用的。 - Nir

6
/^[0-9\+]{1,}[0-9\-]{3,15}$/

首先是一个数字或加号,然后是一些数字或减号。


6

以下是埃塞俄比亚电话号码(EthioTelecom和Safaricom)的正则表达式。献给我的埃塞俄比亚开发者同胞们 ;)

phoneExp = /^(^\+251|^251|^0)?(9|7)\d{8}$/;

它匹配以下内容(限制任何不需要的字符在开头和结尾位置)

  • +251912345678
  • 251912345678
  • 0912345678
  • 912345678
  • +251712345678
  • 251712345678
  • 0712345678
  • 712345678

您可以在此网站上测试regexr.


5

首先测试字符串的长度是否在9到15之间。

然后使用以下正则表达式进行验证:

^\+?\d+(-\d+)*$

这是“normal* (special normal*)*”模式的另一种变体,其中“normal”是“\d”,而“special”是“-”。


如果出于某种原因你必须使用正则表达式来计算长度,可以尝试这个:^(?=.{9})(?!.{16})\+?\d+(-\d+)*$。但是在我看来,检查长度的解决方案更加简洁。 - markijbema
1
@markijbema 哎呀 :p 在这种情况下,最好写成(?=.{9,15}) ;) - fge
那么你至少需要一个 $,但我不确定它是否适用于多个 $,但如果可以的话,这确实更加简洁。 - markijbema
1
它确实有效,因为lookaround运算符是锚点,不会消耗任何内容。但这意味着要两次检查输入...即(?=.{9,15}$) - fge

5

我尝试过:

^(1[ \-\+]{0,3}|\+1[ -\+]{0,3}|\+1|\+)?((\(\+?1-[2-9][0-9]{1,2}\))|(\(\+?[2-8][0-9][0-9]\))|(\(\+?[1-9][0-9]\))|(\(\+?[17]\))|(\([2-9][2-9]\))|([ \-\.]{0,3}[0-9]{2,4}))?([ \-\.][0-9])?([ \-\.]{0,3}[0-9]{2,4}){2,3}$

我也处理了像1-97这样的特殊国家代码。以下是我测试过的号码(来自Puneet Lamba和MCattle):

***** PASS *****
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
(+230) 5 911 4450
123345678
(1) 345 654 67
+1 245436
1-976 33567
(1-734) 5465654
+(230) 2 345 6568
***** CORRECTLY FAILING *****
(003) 555-1212
(103) 555-1212
(911) 555-1212
1-800-555-1234p
800x555x1234
+1 800 555x1234
***** FALSE POSITIVES *****
180055512345
1 800 5555 1234
+867 800 555 1234
1 (800)  555-1234
86 800 555 1212

原帖地址:正则表达式匹配标准的10位电话号码


3
^(\+\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


3

试试这个

\+?\(?([0-9]{3})\)?[-.]?\(?([0-9]{3})\)?[-.]?\(?([0-9]{4})\)?

该模式适用于以下情况

  • +123-(456)-(7890)
  • +123.(456).(7890)
  • +(123).(456).(7890)
  • +(123)-(456)-(7890)
  • +123(456)(7890)
  • +(123)(456)(7890)
  • 123-(456)-(7890)
  • 123.(456).(7890)
  • (123).(456).(7890)
  • (123)-(456)-(7890)
  • 123(456)(7890)
  • (123)(456)(7890)

有关此模式的进一步说明,请单击此处


感谢你提醒我注意这个问题。现在已经处理好了 @Toto - an-apluss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接