正则表达式匹配E.164格式的电话号码

82

我需要添加一个正则表达式,匹配所有可能的有效 E.164 格式的电话号码。

这个正则表达式对于北美电话号码来说效果很好,但我需要一个也能适用于国际号码的正则表达式:

^(+1|1)?([2-9]\d\d[2-9]\d{6})$

例如: +13172222222 匹配成功 13172222222 也匹配成功,因为 +1 或者 1 是可选的 3172222222 也匹配成功,因为 +1 或者 1 是可选的 3171222222 不匹配,不是有效的 NANPA 号码。

来源: Freeswitch.org

我还遇到了这个相关问题,但我认为它对我来说太复杂了。在我的情况下,我只是验证一个黑名单条目,将其与 Twilio 的传入数据进行比较;因此,我对国家代码是否有效并不关心。我实际上只需要测试一个号码是否与通用的E.164格式匹配,而不是假设它是一个 NANPA。

为了更好地理解我需要匹配什么,这里有一个来自Twilio 文档的示例:

如果可能,Twilio 请求中的所有电话号码都是以 E.164格式。例如,(415) 555-4345 会以'+14155554345' 的形式传送。但是,有时 Twilio 无法将传入的呼叫者 ID 标准化为 E.164。在这些情况下,Twilio 将报告原始的呼叫者 ID 字符串。

我希望匹配类似于+14155554345的内容,但不包括(415) 555-4345、415555434、555-4345或5554345。正则表达式不应该限制只匹配美国国家代码。基本上,它应该匹配+xxxxxxxxxxx格式。我认为号码可能会更长,因为在英国等国家有多位数字的国家代码。T-Mobile的英国号码是+447953966150,如果我能想到更好的例子,我会更新此内容。


我注意到当你提供你想要匹配的例子时,人们最愿意帮助你... 至少解释一下你知道如何匹配的输入和你不知道如何匹配的输入之间的区别。 - agent-j
抱歉让你等了这么久才找到一个例子。我找不到任何关于E.164格式的清晰文档,所以我包含了Twilio对它们的简介。 - Sean W.
这些仍然看起来像美国电话号码。Freeswitch.org的正则表达式与您的+14155554345匹配(如果您使用\+转义第一个+)。^(\+1|1)?([2-9]\d\d[2-9]\d{6})$ - agent-j
@agent-j 我添加了一个英国的例子。 - Sean W.
对我来说,棘手的部分是扩展名..如果他们输入“+1(999)-999-999 ext. 191”或“11 99 8888 8888 extension 9909”怎么办? - Mike Graf
8个回答

143
接受的答案很好,除了E.164号码可以有最多15位数字。规范也没有指明最小值,所以我不会一定认为是10位。
应该是^\+[1-9]\d{1,14}$ 参见http://en.wikipedia.org/wiki/E.164

30
新西兰服务号码可以只有5位数字,包括国家代码,例如:+64010。也许答案应该更新为 ^\+?\d{5,15}$?或者更好的是 ^\+?[1-9]\d{4,14}$,以考虑没有以0开头的国家代码的事实。个人建议使用 ^\+?[1-9]\d{1,14}$,因为在E.164中没有指定用户号码的最小长度。 - Sergei
是的,那样更好。我没有考虑到第一个数字的特殊情况。 - Graham Davison
1
也许你可以更新你的回答呢?这样其他人就更容易找到他们需要的正则表达式了。 - Sergei
用于 E.164 验证的正则表达式: /^+[0-9]{1,3}.[0-9]{1,14}$/例如:+27.235682811 - Louis Ferreira
29
对于像Twilio这样的服务,E.164电话号码方案中的"+"符号是必需的,因此请删除+后面的问号。 ^+[1-9]\d{1,14}$ - dbinott
显示剩余2条评论

17

我认为在你拥有了一组很好的例子之前,最好使用灵活的正则表达式。这个正则表达式将匹配一个后面跟着10到14个数字的+

^\+?\d{10,14}$

这个表达式可以拆分为以下几部分: ^ 匹配字符串的开头。 \+? 可选匹配一个 + 符号。 \d{10,14} 匹配 10 到 14 位数字。 $ 确保我们在字符串的结尾。

如果你知道某个位置上的数字不能是 1 或 0,那么你可以在该位置使用 [2-9],像这样:

^\+?\d{6,7}[2-9]\d{3}$

[2-9] 表示匹配从 2 到 9 的任何数字(不匹配 0 或 1)。


谢谢!这正是我现在所需要的。如果在学习数字格式化的过程中发现更多信息,我将自己回答这个问题。 - Sean W.
正如ITU所述,E.164的通用格式必须只包含以下分隔的数字: - 国家代码(1至3位数字)-用户号码(最多12位数字)。应为 d {10,15} - warvariuc

4

3

我使用了被接受的答案,但是它在很多情况下都失败了:

对于以下输入情况:

  • 数字不以"+"开头。
  • 数字数量少于9个。

正则表达式失败了。

最终我使用了:

^\+(?:[0-9]?){6,14}[0-9]$

这个完美地解决了问题!


1
我使用了相同的正则表达式(但也允许空格)。这里有解释:https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s03.html - Diego Frehner
1
这对于E.164格式很好用,谢谢。 - Dhanushka Sandaruwan

1

这只匹配像+1617455221116174552211这样的格式

/\A\+?\d{11}\z/

如果您正在使用Twilio和Ruby on Rails,则这尤其有用。


0

你提供的正则表达式应该可以工作,除了需要转义初始的+符号。

/^(\+1|1)?[2-9]\d\d[2-9]\d{6}$/g

感谢提供信息和链接到refiddle的网站,真是一个非常有用的网站!我最终需要匹配不仅仅是美国号码的正则表达式。最初我只提供了美国号码的示例,因为那时候这些是我能找到的唯一格式化的示例,所以引起了混淆。上面的正则表达式仍然对想要匹配E.164格式的美国号码的任何人都很有用。 - Sean W.

0
这个正则表达式 ^\\+?[0-9]{1,3}[ 1-9]\\d{1,14}$ 可以在没有无效正则表达式的情况下工作。

0

被接受的答案对没有“+”符号的数字无效。我根据维基百科的度量标准进行了一些计算,国家代码:1到3位数字,最大值:15,实际电话号码:12(15-3)到14(15-1)位数字。

在这方面的最小值是10。例如,虚拟的美国号码“+14155552671”是最低限度。将其分解,+1是美国国家代码,其余部分都是“区号”+“用户号码”,即将为10。在我的研究中,我找不到少于7位数字(瑞典)且有效的数字。

因此,我必须想出一个正则表达式,它可以与“+”符号一起使用,并且数字必须介于10〜15之间:

^\++?[1-9][0-9]\d{6,14}$

这很有效。您可以在Regex101上检查它。


这也不适用于没有加号的数字16135551212。为什么允许无限制的+?此外,像Twilio这样的服务通常需要+。国家代码也不以0开头。 - dbinott

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