如何使用正则表达式验证电话号码


920

我正在尝试综合使用正则表达式来验证电话号码。理想情况下,它将处理国际格式,但必须处理美国格式,包括以下内容:

  • 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

我会以目前的尝试来回答,但我希望有人能做得更好和/或更优雅。


3
顺便说一句,您应该指定使用的语言。并非所有的正则表达式引擎都具有相同的语法。
AndrewJFord

9
尽管答案涵盖了这种情况,但似乎您忽略了+1而不是1的选项。
埃里克

153
难道不是所有的美国电话号码都要求555输入911吗?
安德鲁·格林

41
相反,555前缀保留用于假冒电话号码。保证这些号码不会连接到实际的电话号码,因此它们经常在电视和电影中使用,以确保观看者不会尝试拨打该号码并最终骚扰一些可怜的无辜者。
rushinge 2010年

49
@rushinge虽然这在几十年前是正确的,但现在不再正确。555前缀仍然很特殊,但是在没有连接555-0100到555-0199的情况下,只有少数数字可以保证终止。但是我很确定安德鲁还是在开玩笑。
亚当·戴维斯

Answers:


515

更好的选择...只是去除输入上的所有非数字字符(“ x”和“ +”符号除外),要小心,因为+44 (0) ...当使用国际前缀时,英国倾向于以非标准形式写数字(在这种情况下,您应该将其(0)全部丢弃)。

然后,最终得到如下值:

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

然后,当您显示时,请重新格式化您的内心内容。例如

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

35
如果允许这些数字来自美国境外,则格式代码将浪费时间。
Daniel Earwicker,2009年

26
一切都很好,但是并不能验证所输入的实际上是电话号码。例如,如果用户不输入必填的10位数字怎么办?这应该与良好的正则表达式验证结合使用。
休·杰弗纳

108
考虑到问题与验证有关,这是一个非常糟糕的答案。
PlexQ 2012年

15
@PlexQ我不同意。最初的问题是尝试处理电话号码验证,因为它试图处理所有可能的格式设置选项。与其尝试解决所有问题,不如输入所有格式化绒毛并将其“预剥离”,直到只有“数字”为止。这样做可以解决2个问题-测试结果现在很容易,并且您现在可以确保为显示而渲染的值都可以一致地设置格式。关于“ Complicator's Gloves”的答案的第一篇评论很好读……有时问题的答案是采用不同的方法。
scunliffe 2012年

29
如此高投票的答案到底是怎么回事?这不会验证任何内容。更糟糕的是,所有其他电话号码验证问题都参考了这个问题……
jlars62,2014年

303

事实证明,至少对于北美,有一个规范,称为NANP

您需要确切指定所需的内容。什么是合法分隔符?空格,破折号和句号?不允许使用分隔符吗?可以使用一个混合定界符(例如+ 0.111-222.3333)吗?如何处理扩展名(例如111-222-3333 x 44444)?特殊号码(例如911)呢?区号是可选的还是必需的?

这是一个7或10位数字的正则表达式,允许扩展名,定界符为空格,破折号或句点:

^(?:(?:\+?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+))?$

7
此处没有扩展部分(我让用户在单独的字段中输入ext):^(?:(?:\ +?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})$
aarona 2010年

18
这是一个仅匹配10位电话号码的版本(不是843-1212的7位数字): /(?:(?:\+?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})/
Brian Armstrong 2010年

8
10位数字接受区号()周围的(),并且不允许在国家代码前加上1(?:(?:(\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})
Brooke。

5
@StevenSoroka过去两年来,我旁边的桌子上一直放着杰弗里·弗里德尔(Jeffrey Friedl)的书,因为正则表达式是我工作的重要部分。真正理解正则表达式需要花费很多时间。有时,此站点的读者只是在寻找现有的解决方案,而不是自己编写,尤其是在电话号码表示等情况极少的领域。
贾斯汀·R.

7
@ fatcat1111我理解这一点,但是这里的大多数响应都是一次性的正则表达式的“我也是”类型,可能不适合您的任何极端情况。这些最终会出现在我尝试使用的所有网站上,并且由于某人使用了半熟的正则表达式(例如:+是电子邮件地址中的有效字符),因此我无法输入邮政编码,电话号码或电子邮件地址)。此页面上的最佳响应将用户指向库,而不是餐巾纸正则表达式。
史蒂文·索罗卡

298
.*

如果用户想给您他们的电话号码,请信任他们以正确处理。如果他们不想给您,那么强迫他们输入有效的号码将把它们发送到竞争对手的站点,或者让他们输入适合您的正则表达式的随机字符串。我什至可能会想查询溢价星座热线的电话号码,然后输入该号码。

我还将以下任何内容视为网站上的有效条目:

"123 456 7890 until 6pm, then 098 765 4321"  
"123 456 7890 or try my mobile on 098 765 4321"  
"ex-directory - mind your own business"

202
我在这里同意这种观点,但是有时在电话号码实际上将用于用户利益的重要事情上时,执行验证非常好。最好的例子是信用卡授权购买。如果电话号码错误,验证可能会失败。
Pointy

53
如果用户不想输入他的电话号码,您可以允许该字段为可选字段,但是要求用户输入有效的电话号码(如果他们要输入一个电话号码)是否过多?
乔尔·麦克贝斯

11
验证的作用还只是提醒人们添加区号等,他们可能不记得要添加区号,但是事后无法猜测。
本·麦金太尔

29
@Pointy但是正则表达式验证不会帮助您。验证电话号码是否正确的一种唯一方法是实际向其发送消息(对于手机),并确保用户使用某种验证码进行确认。当数字正确性很重要时,这就是您要做的。其他所有内容只是为了方便用户,以防止出现某些(但不是全部)拼写错误,并且不会验证任何内容。
Alex B

14
凉。我的电话号码是1'或1 = 1-PWNED。参见xkcd.com/327owasp.org/index.php/Testing_for_SQL_Injection_(OWASP-DV-005)–
亚伦·牛顿

171

我还建议您查看“ libphonenumber ” Google图书馆。我知道它不是正则表达式,但它确实可以满足您的要求。

例如,它将认识到:

15555555555

是可能的数字,但不是有效的数字。它还支持美国以外的国家。

功能亮点:

  • 解析/格式化/验证世界上所有国家/地区的电话号码。
  • getNumberType-根据数字本身获取数字的类型;能够区分固定电话,移动电话,免费电话,附加费率,共享费用,VoIP和个人号码(在可行的情况下)。
  • isNumberMatch -确定两个数字是否可以相同的置信度。
  • getExampleNumber/ getExampleNumberByType-提供适用于所有国家/地区的有效示例号码,并提供指定需要哪种类型的示例电话号码的选项。
  • isPossibleNumber -仅使用长度信息即可快速猜测数字是否为可能的电话号码,比完全验证要快得多。
  • isValidNumber -使用长度和前缀信息对区域的电话号码进行完全验证。
  • AsYouTypeFormatter -当用户输入每个数字时,即时格式化电话号码。
  • findNumbers -在文本输入中查找数字。
  • PhoneNumberOfflineGeocoder -提供与电话号码有关的地理信息。

例子

电话号码验证的最大问题是它在很大程度上取决于文化。

  • 美国
    • (408) 974–2042有效的美国号码
    • (999) 974–2042不是有效的美国号码
  • 澳大利亚
    • 0404 999 999有效的澳大利亚号码
    • (02) 9999 9999也是有效的澳大利亚号码
    • (09) 9999 9999不是有效的澳大利亚号码

使用正则表达式可以检查电话号码的格式,但实际上并不能检查电话号码的有效性

我建议跳过一个简单的正则表达式来测试您的电话号码,并使用诸如Google的库libphonenumber(链接到GitHub项目)

介绍libphonenumber!

使用其中一个更复杂的示例,1-234-567-8901 x1234您可以获得以下数据libphonenumber(链接到在线演示)

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results:

E164 format                    +12345678901
Original format                (234) 567-8901 ext. 123
National format                (234) 567-8901 ext. 123
International format           +1 234-567-8901 ext. 123
Out-of-country format from US  1 (234) 567-8901 ext. 123
Out-of-country format from CH  00 1 234-567-8901 ext. 123

因此,您不仅可以了解电话号码是否有效(它是正确的),还可以在您的语言环境中获得一致的电话号码格式。

另外,libphonenumber还有许多数据集可以检查电话号码的有效性,因此检查数字(如+61299999999的国际版本(02) 9999 9999)会以格式的形式作为有效数字返回:

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     true

Formatting Results

E164 format                    +61299999999
Original format                61 2 9999 9999
National format                (02) 9999 9999
International format           +61 2 9999 9999
Out-of-country format from US  011 61 2 9999 9999
Out-of-country format from CH  00 61 2 9999 9999

libphonenumber还为您提供了许多其他好处,例如获取被检测到的电话号码所在的位置,以及从电话号码中获取时区信息:

PhoneNumberOfflineGeocoder Results
Location        Australia

PhoneNumberToTimeZonesMapper Results
Time zone(s)    [Australia/Sydney]

但是无效的澳大利亚电话号码((09) 9999 9999)会返回它不是有效的电话号码。

Validation Results

Result from isPossibleNumber()  true
Result from isValidNumber()     false

Google的版本具有用于Java和Javascript的代码,但是人们还实现了使用Google i18n电话号码数据集的其他语言的库:

除非您确定始终要接受一种语言环境的号码,并且始终采用一种格式,否则我强烈建议您不要为此编写自己的代码,而应使用libphonenumber验证和显示电话号码。


他指出,现在还有围棋端口在:github.com/ttacon/libphonenumber
michaelhanson

检查是否可以输入数字时,您是否不需要指定国家/地区代码?我使用的PHP版本,如果我进入像英国数(0替换的实数)07700000000,我得到Missing or invalid default region.的错误。但是,如果我指定国家/地区代码,它将通过。
BugHunterUK

仅供参考:该库不支持某些国家/地区,phpinterviewquestions.co.in
blog/

1
@BugHunterUK(以及所有遇到此问题并想知道相同问题的人)在解析数字时,可以指定期望的区域,并且库将在该区域中查找非国际数字。如果您未指定,它将拒绝任何无效的国际格式。
IMSoP

考虑一下github.com/nyaruka/phonenumbers,因为它已经成为Google推荐的“官方” Go软件包,而不是libphonenumber。
DeeZone

78

/^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i

这符合:

 - (+351) 282 43 50 50
 - 90191919908
 - 555-8909
 - 001 6867684
 - 001 6867684x1
 - 1 (234) 567-8901
 - 1-234-567-8901 x1234
 - 1-234-567-8901 ext1234
 - 1-234 567.89/01 ext.1234
 - 1(234)5678901x1234
 - (123)8575973
 - (0055)(123)8575973

在$ n上,可以节省:

  1. 国家指标
  2. 电话号码
  3. 延期

您可以在https://www.regexpal.com/?fam=99127上对其进行测试


这是我所见过的最全面的正则表达式。在您删除之前很容易解决问题^$否则我可以使用[111] [111] [1111]111--111--1111类似方法解决问题。(对不起,删除了我的最后评论)
bafromca 2014年

您能改一下吗?我无法理解:“除非删除^和$,否则很容易弄乱,否则我可以使用[111] [111] [1111]解决该问题。” 这是否表示您在^和时使用'[111] [111] [1111]'进行验证$
Ismael Miguel

我在你的正则表达式使用[111] [111] [1111],并111--111--1111直到我删除^,并$从正则表达式。
bafromca 2014年

11
^^^这是为什么注释线程不应聊天的一个很好的例子。我对这次对话的结果非常感兴趣,需要知道这个ReGex是否足够坚固,可以在我的应用程序中使用。不幸的是,聊天对话现在消失了。
Matt Cashatt 2014年

1
老实说,我没有去聊天。多次询问解释后,我一无所有。您总是可以使用多种格式的在线数字自己尝试一下。我尝试过的一件事是使用多个电话号码,但是如果周围有空格,则效果不佳。而且我必须找到一种解决方案来计算数字的数量并强制执行特定的数量。
Ismael Miguel 2014年

63

尽管剥离所有空格的答案很简洁,但它并不能真正解决所提出的正则表达式问题。以我的测试脚本为例,该脚本下载一个网页并使用正则表达式提取所有电话号码。由于仍然需要正则表达式,因此您最好让正则表达式完成所有工作。我想出了这个:

1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?

这是一个测试Perl的脚本。匹配时,$ 1包含区号,$ 2和$ 3包含电话号码,$ 5包含分机号。我的测试脚本从Internet下载文件,并在其中打印所有电话号码。

#!/usr/bin/perl

my $us_phone_regex =
        '1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?';


my @tests =
(
"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",
"not a phone number"
);

foreach my $num (@tests)
{
        if( $num =~ m/$us_phone_regex/ )
        {
                print "match [$1-$2-$3]\n" if not defined $4;
                print "match [$1-$2-$3 $5]\n" if defined $4;
        }
        else
        {
                print "no match [$num]\n";
        }
}

#
# Extract all phone numbers from an arbitrary file.
#
my $external_filename =
        'http://web.textfiles.com/ezines/PHREAKSANDGEEKS/PnG-spring05.txt';
my @external_file = `curl $external_filename`;
foreach my $line (@external_file)
{
        if( $line =~ m/$us_phone_regex/ )
        {
                print "match $1 $2 $3\n";
        }
}

编辑:

您可以在正则表达式中将\ W *更改为\ s * \ W?\ s *,以将其收紧。我并不是在考虑正则表达式方面的,例如,在我编写表单时验证表单上的用户输入,但是这种更改使得可以将正则表达式用于此目的。

'1?\s*\W?\s*([2-9][0-8][0-9])\s*\W?\s*([2-9][0-9]{2})\s*\W?\s*([0-9]{4})(\se?x?t?(\d*))?';

2
仅供参考,正则表达式也可以匹配:(4570457-6789这是非常常见的错字。比赛组也偏斜:rubular.com/r/TaTP0mHL5c
SooDesuNe

@SooDesuNe前置(^|[^\d\n])(启用多行标志)可以避免普遍的问题,因为可以确保它没有紧跟数字。
btown

请注意,这是以北美为中心的-错过了“ 44 7911 123456”
本·惠勒

43

在决定也将我的答案作为该线程的答案之前,我在另一个SO问题上回答了这个问题,因为没有人在解决如何要求/不要求物品的问题,只是分发正则表达式:正则 表达式工作错误,匹配了意外的事情

从该站点上的帖子中,我创建了一个快速指南,可以帮助任何人针对自己所需的电话号码格式制作自己的正则表达式,我将警告您(如我在其他站点上所做的那样),如果您的限制过于严格,您可能无法获得理想的结果,并且没有“一刀切”的解决方案来接受世界上所有可能的电话号码-仅是您决定接受的电话格式。使用风险自负。

快速备忘单

  • 开始表达式: /^
  • 如果需要空格,请使用: [\s]\s
  • 如果需要括号,请使用: [(][)]。使用\(\)很难看,可能会使事情变得混乱。
  • 如果您希望任何东西都可选,请在?其后放一个
  • 如果需要连字符,只需键入-[-]。但是,如果您未将其放在其他一系列字符的开头或结尾,则可能需要转义它: \-
  • 如果要在插槽中接受其他选择,请在选项周围加上方括号:[-.\s]需要连字符,句号或空格。最后一个括号后面的问号将使所有这些对于该插槽都是可选的。
  • \d{3}:需要3位数字:000-999。的简写 [0-9][0-9][0-9]
  • [2-9] :该插槽要求数字2-9。
  • (\+|1\s)?:接受一个“加号”或1和一个空格(竖线字符|,是“或”),并将其设置为可选。“加号”必须转义。
  • 如果要让特定数字与插槽匹配,请输入它们:[246]需要2、4或6。 [77|78]需要77或78。
  • $/ :结束表达式

1
这非常有用,但我怀疑并正在寻找{min,max}表达式。你能帮我吗?
Ataboy Josef 2015年

如果我们正在谈论的是一位数字(并且您可以根据它进行匹配),请参阅[2-9]我在此处输入的内容。这意味着您的最小值是2,最大值是9。相应地进行调整。
vapcguy 2015年

30

我写得最简单(尽管我不需要点)。

^([0-9 \(\)\ / \ + \-] *)$

如下所述,它仅检查字符,而不检查其结构/顺序


38
这可以验证大量技术上无效的数字。例如“-+()()())())))”。学习阅读正则表达式,以便您了解自己在做什么。
史蒂文·索罗卡

3
@StevenSoroka从技术上讲,它可能允许很多无效案例,但是当我们考虑仅通过最简单的解决方案帮助用户避免常见错误时,这就是要走的路:)
happyhardik 2013年

2
这也匹配空白,空行
Wasim A.

1
@HappyHardik。确实。简单而强大,通过基本验证,用户可以输入多个点,破折号,方括号或加号。
dijipiji 2014年

刚刚使用它,在很多方面都是错误的。例如,英国电话号码可能以+44开头,或者电话号码里面可能有(0)。但这根据您的正则表达式是无效的。我会推荐@Ismael Miguel的答案。它工作正常,我建议您修改答案。
Stelios Voskos,2015年

22

如果您只想验证您在该字段中没有随机垃圾(即来自垃圾邮件发送者),则此正则表达式应该做得很好:

^[0-9+\(\)#\.\s\/ext-]+$

请注意,对于多少个数字或这些数字中的有效数字没有任何特殊规则,它仅验证仅数字,括号,破折号,加号,空格,磅,星号,句点,逗号或字母ext都存在。

它应该与国际号码和本地化格式兼容。您预见某些区域是否需要使用方括号,大括号或尖括号?(当前不包括在内)。

如果您想维护个位数的规则(例如,美国区号和前缀(交换码)必须在200-999范围内),请祝您好运。维持一个复杂的规则集,这在世界上任何国家将来都可能会过时,这听起来并不有趣。

而且,尽管剥离所有/大多数非数字字符在服务器端可能效果很好(特别是如果您打算将这些值传递给拨号程序),但您可能不希望在验证期间破坏用户的输入,尤其是如果您希望它们在另一个领域进行更正。


22

请注意,剥离()字符不适用于以下常见的书写英国号码的样式:+44 (0) 1234 567890这意味着拨打国际号码:
+441234567890
或在英国拨盘中01234567890



12

我尝试使用无限制的正则表达式:

/^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/

接受:

+(01) 123 (456) 789 ext555
123456
*44 123-456-789 [321]
123456
123456789012345678901234567890123456789012345
*****++[](][((( 123456tteexxttppww

拒绝:

mob 07777 777777
1234 567 890 after 5pm
john smith
(empty)
1234567890123456789012345678901234567890123456
911

您需要对其进行消毒以进行显示。验证后,它可能是一个数字。


12

我发现这很好用:

^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$

它适用于以下数字格式:

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
1-234-567-8901 ext. 1234
(+351) 282 433 5050

确保使用全局和多行标志来确保。

链接:http//www.regexr.com/3bp4b


11

如果您在谈论表单验证,则由于国家/地区和提供者标准的不同,用于验证正确含义以及正确数据的正则表达式将变得极为复杂。也将很难保持最新。

我将问题解释为正在寻找一种广泛有效的模式,该模式可能在内部不一致(例如,具有一组有效的数字,但没有验证中继线,交换机等)是否为国家/地区代码前缀的有效模式。

北美很简单,对于国际人来说,我更喜欢使用一种“惯用的”模式,该模式涵盖人们指定和记住其号码的方式:

^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$

北美模式可确保是否同时包含两个括号。国际号码是可选的初始“ +”和国家/地区代码。之后,您就成语了。有效匹配为:

  • (xxx)xxx-xxxx
  • (xxx)-xxx-xxxx
  • (xxx)xxx-xxxx x123
  • 12 1234 123 1 x1111
  • 12 12 12 12 12
  • 12 1 1234 123456 x12345
  • +12 1234 1234
  • +12 12 12 1234
  • +12 1234 5678
  • +12 12345678

由于我的经验仅限于北美,欧洲和一小部分亚洲地区,因此这可能会产生偏差。


我一直在尝试在我的JavaScript验证脚本中实现上述功能,但始终收到invalid quantifier错误消息。关于我在做什么错的任何想法吗?
Jannis

我会添加一些琐碎的案例,其中指定的电话中没有符号,但可能包含空格和国家/地区代码,在欧洲,本地和移动电话号码通常采用以下格式:676412342、676 46 32
12、676

11

这是一个非常棒的模式,与我需要完成的验证最接近。我不是原始作者,但我认为值得分享,因为我发现这个问题非常复杂,没有简明或有用的答案。

以下正则表达式将以各种全球电话号码格式捕获广泛使用的数字和字符组合:

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

正数:
+42 555.123.4567
+ 1-(800)-123-4567
+7 555 1234567
+7(926)1234567
(926)1234567
+79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567
469 123 45 67
89261234567
8(926)1234567
926.123.4567
415-555-1234
650-555-2345
(416)555-3456
202 555 4567
4035555678
1 416 555 9292

负数:
926 3 4
8 800 600-APPLE

原始资料来源:http//www.regexr.com/38pvb


这对扩展的支持有限。它匹配“ 616-555-1234 x567”,但不匹配“ 616-555-1234 ext。567”。
乔恩·施耐德

2
假阳性,例如“ -------((((((((55555555“或” 99999999999999999999999“
mikep

它无法验证尼瑟兰·麦克唐纳数+31 76 596 4192(我只是在测试随机数)
BIOHAZARD

10

对这个话题的大量答复使我的直觉得到了加强-对这个问题的解决方案实际上是无数种,但没有一个是优雅的。

老实说,我建议您不要尝试验证电话号码。即使您可以编写一个大而笨拙的验证程序,允许所有不同的合法格式,但最终它甚至可以允许几乎所有与电话号码相似的内容。

我认为,最优雅的解决方案是验证最小长度,仅此而已。


在尝试了其中一些方法并浏览了现有数据和用户的反馈后,我倾向于同意……
Christopher King

有时您需要进行验证。如果我要发送确认代码,则不能仅将代码发送到垃圾邮件发送者在该字段中输入的任何随机垃圾中。我想确保该号码可能是电话号码,然后再浪费资源发送它。
路加福音

10

这是菲律宾手机号码的简单正则表达式模式:

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

要么

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

将符合以下条件:

+63.917.123.4567  
+63-917-123-4567  
+63 917 123 4567  
+639171234567  
09171234567  

第一个将匹配任何两位数字的国家代码,而第二个将仅匹配菲律宾的国家代码。

在这里测试:http : //refiddle.com/1ox


谢谢。带区号(如028231234)的座机号码怎么样?我想知道区号是否仅为2-3位数字,并且它们始终始终以0开头吗?
2014年

9

到目前为止,这是我最好的尝试。它处理上面的格式,但是我确定我缺少其他可能的格式。

^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$

9

您将很难用一个/简单的正则表达式来处理国际号码,有关国际(甚至北美)电话号码的困难,请参阅此文章

您需要解析前几位数字来确定国家/地区代码,然后根据国家/地区采取不同的行动。

除此之外-您列出的清单不包括另一种常见的美国格式-省略了首字母缩写1。美国的大多数手机都不需要它,除非您没有拨打国际电话,否则它将开始困扰年轻一代。

您已正确确定这是一个棘手的问题...

-亚当


没有提供的解决方案。有可能的。仅仅因为棘手或复杂并不意味着您应该举起手臂。
Eric Hodonsky

7

阅读完这些答案后,似乎没有一个简单的正则表达式可以解析一堆文本并提取任何格式的电话号码(包括带加号和不带加号的国际电话)。

这是我最近在一个客户项目中使用的内容,在这里我们不得不将所有格式的所有电话号码都转换为tel:链接。

到目前为止,它一直在处理他们抛出的所有问题,但是如果出现错误,我将更新此答案。

正则表达式:

/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/

PHP函数将所有电话号码替换为tel:链接(以防万一有人好奇):

function phoneToTel($number) {
    $return = preg_replace('/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
    return $return;
}

此正则表达式匹配+1 1234562222222222222222222222
VardaElentári2015年

为什么不回来呢?
thexande

“ 9999999999999999999999999999999999999999999”的误报
Ben Wheeler

6

我相信Number :: Phone :: USRegexp :: Common (特别是Regexp :: Common :: URI :: RFC2806的来源)Perl模块可以提供帮助。

应该更详细地说明问题,以说明验证数字的目的。例如,911在美国是有效数字,但911x不适用于x的任何值。这样一来,电话公司便可以计算出拨号的时间。在此问题上有几种变体。但是您的正则表达式不会检查区号部分,因此这似乎不是问题。

就像验证电子邮件地址一样,即使您有一个有效的结果,也要等到尝试使用它才能知道它是否已分配给某人。

如果要验证用户输入,为什么不对结果进行归一化处理呢?如果用户输入了一个您无法识别为有效数字的数字,请将该数字另存为输入的字符,或者去除不重复的字符。该编号::电话::正常化的Perl模块可能是灵感的源泉。


在这里,我要大声疾呼地说,在此正则表达式的几乎所有应用中,允许911作为电话号码可能是一个坏主意。虽然好捕获。
Nicholas Flynt

4

我在一家市场研究公司工作,我们必须过滤所有类型的输入。您太复杂了。只需剥离非字母数字字符,然后查看是否有扩展名。

为了进行进一步的分析,您可以订阅众多提供商之一,该提供商将使您可以访问有效号码的数据库,并告诉您它们是座机还是手机,未连接等。这需要花钱。


验证?123%$)*%()$ *()#456 *()* $#(*(#$ @ 8908将匹配您的建议的解决方案。
PlexQ

1
@PlexQ 555-123-1234、07777777777、90210、01 / 01/1901-用户通过验证夯实垃圾。最好不要使用过分严格的验证并告诉他们他们错了,以免真正发现确实有一些奇怪数据的人。
ReactiveRaven 2012年

4

对格式字符进行替换,然后检查其余字符的电话有效性。在PHP中,

 $replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed
 preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );

这样破坏一个复杂的正则表达式可能同样有效,但更为简单。


3

我发现这很有趣。我没有测试过,但看起来好像可以用

<?php
/*
string validate_telephone_number (string $number, array $formats)
*/

function validate_telephone_number($number, $formats)
{
$format = trim(ereg_replace("[0-9]", "#", $number));

return (in_array($format, $formats)) ? true : false;
}

/* Usage Examples */

// List of possible formats: You can add new formats or modify the existing ones

$formats = array('###-###-####', '####-###-###',
                 '(###) ###-###', '####-####-####',
                 '##-###-####-####', '####-####', '###-###-###',
                 '#####-###-###', '##########');

$number = '08008-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '123-555-555';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1800-1234-5678';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '(800) 555-123';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}

echo "<br />";

$number = '1234567890';

if(validate_telephone_number($number, $formats))
{
echo $number.' is a valid phone number.';
}
?>

4
您的消息似乎表明您没有编写此代码。您介意引用来源吗?
Alastair Irvine


3

为此,使用蒙版输入可能会更好。这样,用户只能输入数字,并且可以设置格式(如果您认为合适)。我不确定这是否适用于Web应用程序,但是如果它是一个非常点击的jQuery插件,它提供了一些执行此操作的选项。

http://digitalbush.com/projects/masked-input-plugin/

他们甚至在教程中讨论了如何隐藏电话号码输入。


3

这是在JavaScript中效果很好的一种。它在字符串中,因为这就是Dojo小部件所期望的。

它与带有可选扩展名的10位北美NANP号匹配。空格,破折号和句点是可接受的定界符。

"^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$"

3

我一直在同一个问题上挣扎,试图使我的应用程序成为未来的证明,但是这些家伙使我朝着正确的方向前进。我实际上并没有检查数字本身是否起作用,我只是在尝试确保输入的一系列数字可能有扩展名也可能没有扩展名。

最糟糕的情况是,如果用户不得不从XML文件中提取未格式化的号码,他们仍然只会在电话的数字键盘中键入数字012345678x5,没有真正的理由保持美观。这种RegEx对我来说会是这样的:

\d+ ?\w{0,9} ?\d+
  • 01234467 extension 123456
  • 01234567x123456
  • 01234567890

2

我的倾向是同意剥离数字并仅接受最好的内容。也许要确保至少存在几个数字,尽管这样做确实禁止例如字母电话号码“ ASK-JAKE”之类的东西。

几个简单的perl表达式可能是:

@f = /(\d+)/g;
tr/0-9//dc;

使用第一个将数字组保持在一起,这可能会提供格式提示。用第二个小数字扔掉所有非数字。

是否担心可能需要暂停然后再输入更多键?还是像555-1212(等待哔哔声)123之类的东西?


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

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


2

对于有兴趣使用爱尔兰手机号码进行类似操作的任何人,这是一种简单的方法:

http://ilovenicii.com/?p=87

的PHP


<?php
$pattern = "/^(083|086|085|086|087)\d{7}$/";
$phone = "087343266";

if (preg_match($pattern,$phone)) echo "Match";
else echo "Not match";

该链接上还有一个JQuery解决方案。

编辑:

jQuery解决方案:

    $(function(){
    //original field values
    var field_values = {
            //id        :  value
            'url'       : 'url',
            'yourname'  : 'yourname',
            'email'     : 'email',
            'phone'     : 'phone'
    };

        var url =$("input#url").val();
        var yourname =$("input#yourname").val();
        var email =$("input#email").val();
        var phone =$("input#phone").val();


    //inputfocus
    $('input#url').inputfocus({ value: field_values['url'] });
    $('input#yourname').inputfocus({ value: field_values['yourname'] });
    $('input#email').inputfocus({ value: field_values['email'] }); 
    $('input#phone').inputfocus({ value: field_values['phone'] });



    //reset progress bar
    $('#progress').css('width','0');
    $('#progress_text').html('0% Complete');

    //first_step
    $('form').submit(function(){ return false; });
    $('#submit_first').click(function(){
        //remove classes
        $('#first_step input').removeClass('error').removeClass('valid');

        //ckeck if inputs aren't empty
        var fields = $('#first_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<12 || value==field_values[$(this).attr('id')] ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }
        });        

        if(!error) {
            if( $('#password').val() != $('#cpassword').val() ) {
                    $('#first_step input[type=password]').each(function(){
                        $(this).removeClass('valid').addClass('error');
                        $(this).effect("shake", { times:3 }, 50);
                    });

                    return false;
            } else {   
                //update progress bar
                $('#progress_text').html('33% Complete');
                $('#progress').css('width','113px');

                //slide steps
                $('#first_step').slideUp();
                $('#second_step').slideDown();     
            }               
        } else return false;
    });

    //second section
    $('#submit_second').click(function(){
        //remove classes
        $('#second_step input').removeClass('error').removeClass('valid');

        var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;  
        var fields = $('#second_step input[type=text]');
        var error = 0;
        fields.each(function(){
            var value = $(this).val();
            if( value.length<1 || value==field_values[$(this).attr('id')] || ( $(this).attr('id')=='email' && !emailPattern.test(value) ) ) {
                $(this).addClass('error');
                $(this).effect("shake", { times:3 }, 50);

                error++;
            } else {
                $(this).addClass('valid');
            }


        function validatePhone(phone) {
        var a = document.getElementById(phone).value;
        var filter = /^[0-9-+]+$/;
            if (filter.test(a)) {
                return true;
            }
            else {
                return false;
            }
        }

        $('#phone').blur(function(e) {
            if (validatePhone('txtPhone')) {
                $('#spnPhoneStatus').html('Valid');
                $('#spnPhoneStatus').css('color', 'green');
            }
            else {
                $('#spnPhoneStatus').html('Invalid');
            $('#spnPhoneStatus').css('color', 'red');
            }
        });

     });

        if(!error) {
                //update progress bar
                $('#progress_text').html('66% Complete');
                $('#progress').css('width','226px');

                //slide steps
                $('#second_step').slideUp();
                $('#fourth_step').slideDown();     
        } else return false;

    });


    $('#submit_second').click(function(){
        //update progress bar
        $('#progress_text').html('100% Complete');
        $('#progress').css('width','339px');

        //prepare the fourth step
        var fields = new Array(
            $('#url').val(),
            $('#yourname').val(),
            $('#email').val(),
            $('#phone').val()

        );
        var tr = $('#fourth_step tr');
        tr.each(function(){
            //alert( fields[$(this).index()] )
            $(this).children('td:nth-child(2)').html(fields[$(this).index()]);
        });

        //slide steps
        $('#third_step').slideUp();
        $('#fourth_step').slideDown();            
    });


    $('#submit_fourth').click(function(){

        url =$("input#url").val();
        yourname =$("input#yourname").val();
        email =$("input#email").val();
        phone =$("input#phone").val();

        //send information to server
        var dataString = 'url='+ url + '&yourname=' + yourname + '&email=' + email + '&phone=' + phone;  



        alert (dataString);//return false;  
            $.ajax({  
                type: "POST",  
                url: "http://clients.socialnetworkingsolutions.com/infobox/contact/",  
                data: "url="+url+"&yourname="+yourname+"&email="+email+'&phone=' + phone,
                cache: false,
                success: function(data) {  
                    console.log("form submitted");
                    alert("success");
                }
                });  
        return false;

   });


    //back button
    $('.back').click(function(){
        var container = $(this).parent('div'),
        previous  = container.prev();

        switch(previous.attr('id')) {
            case 'first_step' : $('#progress_text').html('0% Complete');
                  $('#progress').css('width','0px');
                       break;
            case 'second_step': $('#progress_text').html('33% Complete');
                  $('#progress').css('width','113px');
                       break;

            case 'third_step' : $('#progress_text').html('66% Complete');
                  $('#progress').css('width','226px');
                       break;

        default: break;
    }

    $(container).slideUp();
    $(previous).slideDown();
});


});

来源

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.