我试图把一个全面的正则表达式放在一起来验证电话号码。理想情况下,它可以处理国际格式,但它必须处理美国格式,包括以下内容:

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

我会用我目前的尝试来回答,但我希望有人有更好的和/或更优雅的东西。


当前回答

我也在为同样的问题而挣扎,试图让我的应用程序经得起未来的考验,但这些人让我走上了正确的方向。我实际上并不是在检查数字本身,看它是否有效,我只是试图确保输入的一系列数字可能有或没有扩展名。

最坏的情况是,如果用户必须从XML文件中提取一个未格式化的数字,他们仍然只是将数字输入到手机的数字pad 012345678x5中,没有真正的理由保持它的美观。这种RegEx对我来说是这样的:

\d+ ?\w{0,9} ?\d+

01234467分机号123456 01234567 x123456 01234567890

其他回答

我在另一个SO问题上回答了这个问题,然后决定把我的答案也包括在这个线程上,因为没有人解决如何要求/不要求项目,只是分发正则表达式: 正则表达式工作错误,匹配意想不到的东西

从我在那个网站上的帖子中,我创建了一个快速指南,帮助任何人为自己想要的电话号码格式制作自己的正则表达式,我要警告(就像我在另一个网站上所做的那样),如果你限制太多,你可能不会得到想要的结果,并且没有“一宜之计”的解决方案来接受世界上所有可能的电话号码——只有你决定接受的格式作为你选择的格式。使用风险自负。

快速小抄

Start the expression: /^ If you want to require a space, use: [\s] or \s If you want to require parenthesis, use: [(] and [)] . Using \( and \) is ugly and can make things confusing. If you want anything to be optional, put a ? after it If you want a hyphen, just type - or [-] . If you do not put it first or last in a series of other characters, though, you may need to escape it: \- If you want to accept different choices in a slot, put brackets around the options: [-.\s] will require a hyphen, period, or space. A question mark after the last bracket will make all of those optional for that slot. \d{3} : Requires a 3-digit number: 000-999. Shorthand for [0-9][0-9][0-9]. [2-9] : Requires a digit 2-9 for that slot. (\+|1\s)? : Accept a "plus" or a 1 and a space (pipe character, |, is "or"), and make it optional. The "plus" sign must be escaped. If you want specific numbers to match a slot, enter them: [246] will require a 2, 4, or 6. (?:77|78) or [77|78] will require 77 or 78. $/ : End the expression

既然写电话号码有很多选择, 我们可以测试其中有足够的数字,不管它们是如何分开的。我发现9到14个数字适合我:

^\D*(\d\D*){9,14}$

正确的:

123456789 1234567890123 +123 (456) 78.90-98.76

错误的:

123 (1234) 1234 9007199254740991 我不会按你说的去做 +123 (456) 78.90-98.76 #543 ext 210>2>5>3 早上打456-7890 18:00后打987 - 54-3210找雪莉

如果你想支持最后两个例子,只需要移除上限:

(\d\D*){9,}

(如果没有上限,则不需要^$)

我还建议查看“libphonenumber”谷歌库。我知道它不是正则表达式,但它确实是你想要的。

例如,它会识别:

15555555555

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

功能亮点:

Parsing/formatting/validating phone numbers for all countries/regions of the world. getNumberType - gets the type of the number based on the number itself; able to distinguish Fixed-line, Mobile, Toll-free, Premium Rate, Shared Cost, VoIP and Personal Numbers (whenever feasible). isNumberMatch - gets a confidence level on whether two numbers could be the same. getExampleNumber/getExampleNumberByType - provides valid example numbers for all countries/regions, with the option of specifying which type of example phone number is needed. isPossibleNumber - quickly guessing whether a number is a possible phonenumber by using only the length information, much faster than a full validation. isValidNumber - full validation of a phone number for a region using length and prefix information. AsYouTypeFormatter - formats phone numbers on-the-fly when users enter each digit. findNumbers - finds numbers in text input. PhoneNumberOfflineGeocoder - provides geographical information related to a phone number.

例子

电话号码验证最大的问题是它非常依赖文化。

美国 (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)99999999的国际版本)这样的号码,返回一个带有格式的有效号码:

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)99999999)返回它不是一个有效的电话号码。

Validation Results

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

谷歌的版本有Java和Javascript的代码,但人们也实现了使用谷歌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 灵丹妙药:https://github.com/socialpaymentsbv/ex_phone_number

除非您确定始终接受来自一个地区的数字,并且始终采用同一种格式,否则我强烈建议不要为此编写自己的代码,并使用libphonenumber来验证和显示电话号码。

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

.*

如果用户想要给你他们的电话号码,那么相信他们会把它做好。如果他们不想给你,那么强迫他们输入一个有效的数字,要么把他们送到竞争对手的网站,要么让他们输入一个符合你的正则表达式的随机字符串。我甚至可能会忍不住去查询占星热线的电话号码,然后输入这个号码。

我也会考虑以下任何一个网站上的有效条目:

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