当前位置:  开发笔记 > 编程语言 > 正文

用于电话号码验证的全面正则表达式

如何解决《用于电话号码验证的全面正则表达式》经验,为你挑选了21个好方法。

我正在尝试整合一个全面的正则表达式来验证电话号码.理想情况下它会处理国际格式,但它必须处理美国格式,包括以下内容:

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> scunliffe..:

更好的选择......只需在输入上删除所有非数字字符(除了'x'和前导'+'符号),因为英国倾向于在被+44 (0) ...要求使用国际前缀时以非标准形式写数字(在这种特殊情况下,你应该(0)完全抛弃).

然后,您最终得到如下值:

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

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

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


考虑到问题是关于验证 - 这是一个非常糟糕的答案.
如果允许来自美国以外的号码,则格式化代码将浪费时间.
这个如此高度投票的答案到底是怎么回事?这不是_validate_任何东西.更糟糕的是所有其他电话号码验证问题都参考了这一个......
这很好,但并不能验证输入的内容实际上是电话号码.例如,如果用户没有输入必要的10位数怎么办?这应该与良好的正则表达式验证相结合.
@PlexQ我不同意.最初的问题是尝试处理电话号码验证,因为它试图处理所有可能的格式选项.而不是尝试解决所有问题,而是采取输入并"预先剥离"所有格式化绒毛,直到你只有"数字".这样做可以解决2个问题 - 现在可以轻松测试结果,现在可以确保为显示而呈现的值可以一致地进行格式化.关于"Complicator's Gloves"这个答案的第一个评论是一个很好的解读......有时问题的答案是以不同的方式处理它.
@danilo - !x是为了保持任何"x"字符被剥离,以便可以分离出扩展名.
@ jlars62它可能无法验证电话号码,但它提供的替代解决方案比尝试判断给定电话号码是否有效更可靠 - 考虑到有效的想法在不同国家之间存在显着差异.IMO这是一个很好的解决方案,虽然我同意它不验证它仍然解决了问题.
这很好用,除了像"1-800-CALL-NOW"这样的数字?
上面正则表达式的改进:`/ [^\d + x] | x(?= [^ x]*x)/ gi`防止多个x(使用字符串中的最后一个x)
是的,验证或格式化电话号码不是一个好主意.以下是所有有效的德国电话号码:+49(0)89 12345,+ 49(0)6221 1234.如果你在德国,你可以拨打089 12345或06221 1234,但是来自瑞士它' d为0049 89 12345或0049 6221 1234.所以这就像英国的情况,但我们的区号没有固定的长度.除非您有列表,否则无法正确格式化数字.
不使用正则表达式.+1
string.replace("[^\d +!x]","")
这很好,但它没有回答显式请求RegEx解决方案的提出问题.
@Raymond你可以使用`$ justDigitsOrPlusOrX = preg_replace("/ [^\d + x] /","",$ phoneNum);`去除你不需要的所有字符...然后测试剩下的(如果需要的话)
@Swanand我想在那些场景中,如果这是你真正想要的,你可以启用一个智能翻译,将字母转换为匹配的数字......但我认为这是一个非常特殊的角落案例,而大多数人都是如此.;-)
当你看到一个以"+44(0)"开头的数字时,你需要小心.这是英国一种非常常见的格式,您可能希望将其映射到"+ 44"(即删除"(0)").

2> Justin R...:

事实证明,至少在北美,有一种称为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+))?$


这里是一个版本,仅匹配10个数字的电话号码(不是7位数喜欢843-1212):`/(?:(?:\+?1\s*(?:[.-]\s*))? (?:(\ S*([2-9] 1 [02-9] | [2-9] [2月8日] 1 | [2-9] [2月8日] [02-9])\ S*)|([2-9] 1 [02-9] | [2-9] [2月8日] 1 | [2-9] [2月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})/`
区号附近有10位数字接受(),不允许在1之前作为国家代码`(?:(?:(\s*\(?([2-9] 1 [02-9] | [2-9] ] [2月8日] 1 | [2-9] [2月8日] [02-9])\ S*)|([2-9] 1 [02-9] | [2-9] [02- 8] 1 | [2-9] [2月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})`
这里没有扩展部分(我让我的用户在一个单独的字段中输入ext):^(?:(?:\ +?1\s*(?:[.-]\s*)?)?(? :\(\ S*([2-9] 1 [02-9] | [2-9] [2月8日] 1 | [2-9] [2月8日] [02-9])\ S*\)|([2-9] 1 [02-9] | [2-9] [2月8日] 1 | [2-9] [2月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})$
@ fatcat1111我明白了,但这里的大部分回复都是"我也是"类型的一次性正则表达式,可能不适合你的任何角落情况.这些最终会出现在我尝试使用的所有网站上,我无法输入我的邮政编码或电话号码或电子邮件地址,因为有人使用了半生不熟的正则表达式(例如:+是电子邮件地址中的有效字符) ).此页面上的最佳响应将用户指向库,而不是餐巾纸绘制的正则表达式.
@StevenSoroka过去两年我在桌子旁边有杰弗里弗里德的书,因为正则表达式是我工作的重要部分.真正理解正则表达式需要很长时间.有时候,这个网站的读者只是在寻找一个现有的解决方案,而不是自己编写,特别是在有很多极端情况的域中,比如电话号码表示.
复制这些表达式时,请注意检查不间断的空格.

3> 小智..:
.*

如果用户想要给你他的电话号码,那么请相信他是正确的.如果他不想给你,然后强迫他输入一个有效的号码将把他送到竞争对手的网站或让他输入一个适合你的正则表达式的随机字符串.我甚至可能想要查看优质性别性别的数量,然后输入.

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

"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"


我同意这里的观点,但有时候,当电话号码实际上用于某些重要的*时,为了用户的利益*进行验证是很好的.这里最好的例子是购买的信用卡授权.如果电话号码错误,则验证可能会失败.
如果用户不想输入他的电话号码,你可以只允许该字段是可选的,但如果他们要输入一个有效的电话号码,是否要求用户输入一个?
@Pointy但是正则表达式验证对你没有帮助.实际验证电话号码是否正确的唯一方法是实际向其发送消息(如果是移动电话)并确保用户确认使用某种验证码.当数字正确性很重要时,这就是你要做的.其他一切只是为了方便用户防范某些(但不是全部)拼写错误并且不验证任何内容.
凉.我的电话号码是_1'或1 = 1 - PWNED_.请参阅http://xkcd.com/327/和https://www.owasp.org/index.php/Testing_for_SQL_Injection_(OWASP-DV-005)
此外,验证的作用仅仅是提醒人们添加他们可能不会记得添加的区号等,但事后不可能猜到.
@Pointy:是的,但即使它是一个有效的数字,这并不意味着它是一个现有的数字,即使它存在,也不意味着它是用户的.如果这很重要,你需要建立一个自动系统,打电话给他们检查......如果你的预算延伸到那么远:)
这个答案没有回答这个问题 - 而只是促进形式的不容忍,这种形式已经在我们所有人中固有.*
答案包含最深刻的智慧.
@AaronNewton:在表单级别或使用正则表达式执行验证无论如何都是不安全的,有更好的方法可以防止sql注入.
这种反应是不敬的,与问题无关.OP要求帮助验证用户输入的格式; 不是你个人对他是否应该这样做的看法.潜在用例:该网站用于公司的内部使用 - 不代表内部网的使用,而是该公司的员工在"外地"工作,并通过该网站与办公室员工进行沟通.作为工作要求的一部分,他们需要此人输入可以到达的有效电话号码,并希望避免可能导致令人头疼的简单错误.
如果你想*真正*验证一个电话号码......**PHONE IT !!**这就像人们提出的"验证电子邮件地址"的荒谬正则表达式......如果你真的在乎电子邮件地址有效,然后**发送给他们的电子邮件!!**
我从可用性角度同意,但允许任意输入可能会使您的网站暴露于跨站点脚本(XSS)攻击.恶意用户可能能够在您的自由格式电话号码字符串中注入JavaScript.
问题不在于用户输入验证。可以验证来自多个系统的汇总电话号码列表,这些列表在不同时间以不同的形式收集。脏数据来自各种各样的地方。

4> Halfwarr..:

我还建议查看" 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不是有效的澳大利亚号码

正则表达式适用于检查电话号码的格式,但它实际上无法检查电话号码的有效性.

我建议跳过一个简单的正则表达式来测试你的电话号码,并使用像谷歌这样的库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电话号码数据集的其他语言实现了库:

PHP:https://github.com/giggsey/libphonenumber-for-php

Python:https://github.com/daviddrysdale/python-phonenumbers

Ruby:https://github.com/sstephenson/global_phone

C#:https://github.com/twcclegg/libphonenumber-csharp

Objective-C:https://github.com/iziz/libPhoneNumber-iOS

JavaScript:https://github.com/ruimarinho/google-libphonenumber

Elixir:https://github.com/socialpaymentsbv/ex_phone_number

除非你确定你总是要接受来自一个语言环境的数字,并且它们总是采用一种格式,否则我会建议不要为此编写自己的代码,并使用libphonenumber来验证和显示电话号码.



5> Ismael Migue..:

/^(?:(?:\(?(?: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上,它可以节省:

    国家指标

    电话号码

    延期

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


^^^这是为什么评论线程不应该去聊天的一个很好的例子.我对这个对话的结果非常感兴趣,并且需要知道这个ReGex是否足够坚固,可以在我的应用中使用.不幸的是,聊天对话现在已经消失了.

6> indiv..:

虽然剥离所有空格的答案很简洁,但它并没有真正解决所提出的问题,即找到一个正则表达式.以我的测试脚本为例,下载网页并使用正则表达式提取所有电话号码.既然你还需要一个正则表达式,你也可以让正则表达式完成所有的工作.我想出了这个:

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包含扩展名.我的测试脚本从互联网上下载文件并打印其中的所有电话号码.

#!/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*))?';


仅供参考,正则表达式也匹配:`(4570457-6789`这将是一个非常常见的拼写错误.匹配组也会出现偏差:http://rubular.com/r/TaTP0mHL5c

7> vapcguy..:

我在另一个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.

$/ :结束表达



8> Artjom Kurap..:

我写的最简单(虽然我不需要点).

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

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


这验证了大量技术上无效的数字.比如," - +()()())())))".学习阅读正则表达式,以便了解自己在做什么.
@StevenSoroka在技术上可能会允许很多无效的情况,但是当我们考虑用最简单的解决方案帮助用户避免常见错误时,这就是要走的路:)
这也匹配空白,空行

9> Ben Clifford..:

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



10> Steve..:

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

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

请注意,它没有任何特殊规则来确定有多少位数,或者哪些数字在这些数字中有效,它只是验证只有数字,括号,破折号,加号,空格,磅,星号,句号,逗号或字母e,x,t都存在.

它应该与国际号码和本地化格式兼容.您是否预见到某些地区需要允许方形,卷曲或有角度的括号?(目前不包括在内).

如果你想保持每位数的规则(例如美国区号和前缀(交换代码)必须在200-999范围内),祝你好运.保持一个复杂的规则集,在世界上任何一个国家的任何一点都可能过时,听起来并不好玩.

虽然剥离所有/大多数非数字字符可能在服务器端运行良好(特别是如果您计划将这些值传递给拨号器),您可能不希望在验证期间抖动用户的输入,特别是如果您希望它们在另一个领域进行更正.



11> Rob Wells..:

你看过RegExLib了吗?

输入美国电话号码带来了很多可能性.


这看起来是将晦涩的错误集成到代码中的好方法.

12> ReactiveRave..:

我尝试不受限制的正则表达式:

/^[+#*\(\)\[\]]*([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

由您来清理它以进行显示.验证后,它可能是一个数字.



13> 小智..:

我发现这很好用:

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

确保使用全局AND多行标记来确保.

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



14> 小智..:

如果您正在谈论表单验证,由于国家和提供商的标准不同,用于验证正确含义以及正确数据的正则表达式将非常复杂.它也很难保持最新.

我将这个问题解释为寻找广泛有效的模式,这种模式可能不是内部一致的 - 例如,有一组有效的数字,但没有验证中继线,交换等到国家代码前缀的有效模式.

北美很简单,对于国际而言,我更喜欢使用"惯用"模式,该模式涵盖了人们指定和记住数字的方式:

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

这可能有偏见,因为我的经验仅限于北美,欧洲和亚洲的一小部分.



15> mindplay.dk..:

我对这个主题的回复量增强了我的直觉 - 这个问题几乎有无数的解决方案,其中没有一个会变得优雅.

老实说,我建议你不要试图验证电话号码.即使你可以写一个大,毛茸茸的验证,将允许所有不同的合法形式,这将最终使相当多的东西,甚至远程类似摆在首位的电话号码.

在我看来,最优雅的解决方案是验证最小长度,仅此而已.



16> GaiusSensei..:

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

((\+[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



17> Stuart Kersh..:

这是一个与我需要实现的验证最匹配的精彩模式.我不是原作者,但我认为这很值得分享,因为我发现这个问题非常复杂,没有简洁或广泛有用的答案.

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

/^\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



18> Adam Davis..:

你会很难用单一/简单的正则表达式来处理国际号码,请看这篇关于国际(甚至北美)电话号码困难的帖子.

您需要解析前几个数字以确定国家/地区代码是什么,然后根据国家/地区采取不同的行动.

除此之外 - 您提供的列表不包括另一种常见的美国格式 - 从最初的1开始.美国的大多数手机都不需要它,除非他们拨打国际电话,否则它将开始困扰年轻一代.

你已经正确地发现这是一个棘手的问题......

-亚当



19> Nicholas Tra..:

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

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



20> Drew Thomas..:

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

这是我最近用于客户项目的内容,我们必须将所有格式的电话号码转换为tel:links.

到目前为止,它一直在处理他们所做的一切,但如果出现错误,我会更新这个答案.

正则表达式:

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

PHP函数用tel:links替换所有电话号码(万一有人好奇):

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



21> Jon Ericson..:

我相信Number :: Phone :: US和Regexp :: Common (特别是Regexp :: Common :: URI :: RFC2806的源代码)Perl模块可以提供帮助.

应该更详细地说明问题,以解释验证数字的目的.例如,911在美国是有效数字,但911x不是任何x值.这样,电话公司可以在您完成拨号时进行计算.这个问题有几个变种.但是你的正则表达式不检查区号部分,所以这似乎不是一个问题.

与验证电子邮件地址一样,即使您拥有有效的结果,也无法知道在您尝试之前是否将其分配给某人.

如果您正在尝试验证用户输入,为什么不将结果标准化并完成它?如果用户输入的号码无法识别为有效号码,请将其保存为输入或删除不可用的字符.该编号::电话::正常化的Perl模块可能是灵感的源泉.

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有