A comprehensive regex for phone number validation
我正在尝试建立一个综合的regex来验证电话号码。理想情况下,它可以处理国际格式,但它必须处理美国格式,包括:
- 1-23 4-567—8901
- 1-234-567-8901 x1234
- 1-234-567-8901分机1234
- 1(234)567-8901
- 1.23 4.567.8901
- 1/234/567/8901
- 一百二十三亿四千五百六十七万八千九百零一
我将用我目前的尝试来回答,但我希望有人有更好和/或更优雅的东西。
更好的选择…只需去掉输入端的所有非数字字符(除"x"和前导"+"符号外),注意英国人在要求使用国际前缀时(在这种特定情况下,您应该完全放弃
然后,你会得到如下的值:
1 2 3 4 5 6 7 8 9 | 12345678901 12345678901x1234 345678901x1234 12344678901 12345678901 12345678901 12345678901 +4112345678 +441234567890 |
然后当你显示时,重新格式化到你的心形内容。例如
1 2 | 1 (234) 567-8901 1 (234) 567-8901 x1234 |
事实证明,至少在北美,有一种特殊的东西叫做"保姆"。
您需要准确指定所需的内容。什么是法定分隔符?空格、短划线和句号?不允许使用分隔符?一个混合分隔符(例如+0.111-222.3333)可以吗?如何处理扩展(例如111-222-3333 x 44444)?911之类的特殊号码呢?区号是可选的还是必需的?
这里是一个7或10位数字的regex,允许扩展,分隔符是空格、短划线或句点:
1 | ^(?:(?:\+?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+))?$ |
1 | .* |
如果用户想给你他的电话号码,那就相信他能把它弄好。如果他不想给你,那么强迫他输入一个有效的数字,要么把他送到竞争对手的网站,要么让他输入一个符合你的regex的随机字符串。我甚至可能会想查找一个高利率性热线的号码,然后输入这个号码。
我也会将以下任何一项视为网站上的有效条目:
1 2 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" |
我还建议您查看"libphonenumber"谷歌库。我知道它不是雷杰克斯,但它完全符合你的要求。
例如,它将认识到:
1 | 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的
使用一个更复杂的示例,
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
因此,您不仅可以了解电话号码是否有效(它是有效的),而且还可以在您的区域设置一致的电话号码格式。
另外,
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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还为您提供了许多额外的好处,例如获取检测到电话号码的位置,以及从电话号码获取时区信息:
1 2 3 4 5 | PhoneNumberOfflineGeocoder Results Location Australia PhoneNumberToTimeZonesMapper Results Time zone(s) [Australia/Sydney] |
但是,无效的澳大利亚电话号码(
1 2 3 4 | 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/davidrysdale/python-phonenumbers
- 鲁比:https://github.com/sstephenson/global_phone
- C:https://github.com/twccleg/libphonenumber-csharp
- 目标C:https://github.com/iziz/libphonenumber-ios
- javascript:https://github.com/ruimarinho/google-libphonenumber
- elixir:https://github.com/socialpaymentsbv/ex_电话号码
除非你确定你总是接受一个地区的电话号码,而且他们总是采用一种格式,否则我强烈建议不要为此编写自己的代码,并使用libphonenumber验证和显示电话号码。
这场比赛:
1 2 3 4 5 6 7 8 9 10 11 12 | - (+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。以我的测试脚本为例,该脚本下载网页并使用regex提取所有电话号码。既然你无论如何都需要一个regex,你最好让regex来做所有的工作。我想到了这个:
1 | 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下载一个文件并打印其中的所有电话号码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #!/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] " if not defined $4; print"match [$1-$2-$3 $5] " if defined $4; } else { print"no match [$num] "; } } # # 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 "; } } |
编辑:
您可以将w*更改为s*w吗? s*在regex中拧紧一点。我在编写表单时并没有考虑使用regex来验证用户在表单上的输入,但这种更改使使用regex成为可能。
1 | '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*))?'; |
在决定将我的答案也包括在这个线程的答案中之前,我在另一个so问题上回答了这个问题,因为没有人在解决如何要求/不要求项目,只是分发regex:regex工作错误,匹配意外事件
从我在那个网站上的帖子中,我创建了一个快速指南来帮助任何人为他们自己想要的电话号码格式制作自己的regex,我会警告(就像我在另一个网站上做的那样),如果你限制太多,你可能得不到想要的结果,并且没有"一刀切"的解决方案来接受所有可能的电话号码。世界上-只有你决定接受的作为你选择的格式。自担风险使用。
快速备忘单- 开始表达式:
/^ 。 - 如果需要空间,请使用:
[\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 | ^([0-9\(\)\/\+ \-]*)$ |
如下文所述,它只检查字符,而不检查其结构/顺序。
请注意,删除
如果您只想验证字段中没有随机垃圾(例如,来自表单垃圾邮件发送者),那么这个regex应该做得很好:
1 | ^[0-9+\(\)#\.\s\/ext-]+$ |
注意,它没有任何特殊的规则来确定这些数字中有多少个数字或哪些数字是有效的,它只是验证只有数字、括号、短划线、加号、空格、磅、星号、句点、逗号或字母
它应该与国际号码和本地化格式兼容。对于某些区域,您是否预见到需要使用方括号、花括号或尖括号?(目前不包括在内)。
如果你想保持每个数字的规则(比如美国的区号和前缀(交换码)必须在200-999之间),那么祝你好运。维持一个复杂的规则集,这个规则集在未来任何时候都可能被世界上任何一个国家过时,这听起来并不有趣。
虽然在服务器端剥离所有/大多数非数字字符可能会很好地工作(特别是如果您计划将这些值传递给拨号程序),但您可能不希望在验证期间破坏用户的输入,特别是如果您希望他们在另一个字段中进行更正。
你看过Regexlib吗?
输入我们的电话号码带来了很多可能性。
我觉得这个很管用:
1 | ^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$ |
它适用于以下数字格式:
1 2 3 4 5 6 7 8 9 | 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
我尝试一个无限制的正则表达式:
1 | /^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/ |
接受:
1 2 3 4 5 6 | +(01) 123 (456) 789 ext555 123456 *44 123-456-789 [321] 123456 123456789012345678901234567890123456789012345 *****++[](][((( 123456tteexxttppww |
拒绝:
1 2 3 4 5 6 | mob 07777 777777 1234 567 890 after 5pm john smith (empty) 1234567890123456789012345678901234567890123456 911 |
您可以对其进行消毒以供显示。在验证之后,它可能是一个数字。
如果您谈论的是表单验证,那么验证正确含义和正确数据的regexp将非常复杂,因为不同的国家和提供商标准不同。也很难跟上时代。
我将这个问题解释为寻找一个广泛有效的模式,这种模式在内部可能不一致——例如拥有一组有效的数字,但没有验证主干线、交换等是否符合国家代码前缀的有效模式。
北美是直截了当的,在国际上,我更喜欢使用"惯用"模式,它涵盖了人们指定和记住数字的方式:
1 | ^((((\(\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
这可能有偏见,因为我的经验仅限于北美、欧洲和亚洲的一小部分地区。
我的直觉被对这个话题的大量回复所强化——这个问题的解决方案实际上是无限多的,没有一个会是优雅的。
老实说,我建议你不要尝试验证电话号码。即使你能写一个大的,毛茸茸的验证器,允许所有不同的合法格式,它最终会允许几乎任何东西,甚至在一开始就很像一个电话号码。
在我看来,最优雅的解决方案是验证最小长度,而不是更多。
这是菲律宾手机号码的简单正则表达式模式:
1 | ((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4} |
或
1 | ((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4} |
将匹配这些:
1 2 3 4 5 | +63.917.123.4567 +63-917-123-4567 +63 917 123 4567 +639171234567 09171234567 |
第一个将匹配任何两位数的国家代码,而第二个将只匹配菲律宾国家代码。
在此测试:http://refidle.com/1ox
这里有一个非常好的模式,它最符合我需要实现的验证。我不是最初的作者,但我认为这是值得分享的,因为我发现这个问题非常复杂,没有一个简明或广泛有用的答案。
以下regex将捕获各种全球电话号码格式中广泛使用的号码和字符组合:
阳性:
+42 555.123.4567
+1-(800)-123-4567
+7 555 1234567
+7(926)1234567
(926)1234567
+79261234567
926 1234567
9261234567<BR/>1234567<BR/>123-467123-8901
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<BR/>1 416 555 555
否定的:
926 3 4<BR/>8 800 600苹果
原始资料来源:http://www.regexr.com/38pvb
你很难用一个简单的regex来处理国际号码,请看这篇关于国际(甚至北美)电话号码困难的文章。
您需要解析前几个数字来确定国家代码是什么,然后根据国家采取不同的行动。
除此之外-您提供的列表不包括另一种常见的美国格式-去掉了最初的1。在美国,大多数手机都不需要它,而且它会开始困扰年轻一代,除非他们已经打过国际长途。
你已经确定这是个棘手的问题…
-亚当
在读完这些答案后,似乎没有一个简单的正则表达式可以通过一堆文本进行解析,并以任何格式提取电话号码(包括带有或不带加号的国际电话号码)。
这是我最近在一个客户项目中使用的方法,我们必须将所有格式的电话号码转换为tel:links。
到目前为止,它已经处理了所有他们抛出的东西,但是如果出现错误,我会更新这个答案。
Regex:
php函数将所有电话号码替换为tel:links(如果有人好奇):
1 2 3 4 | 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; } |
这是我迄今为止最好的尝试。它处理上面的格式,但我确信我遗漏了一些其他可能的格式。
1 | ^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$ |
我相信数字::phone::us和regexp::common(尤其是regexp::common::uri::rfc2806的源代码)Perl模块会有所帮助。
应该更详细地说明这个问题,以解释验证数字的目的。例如,911在美国是一个有效的号码,但911X不代表X的任何值。这样电话公司就可以在您拨号后进行计算。这个问题有几个不同之处。但是您的regex不检查区号部分,所以这似乎不是一个问题。
就像验证电子邮件地址一样,即使你有一个有效的结果,在你尝试之前你也不知道它是否被分配给了某人。
如果您试图验证用户输入,为什么不规范化结果并完成它呢?如果用户输入了一个您无法识别为有效数字的数字,请将其保存为输入的或去掉不可使用的字符。编号::phone::normalize perl模块可能是灵感的来源。
我在一家市场调查公司工作,我们必须一直过滤这些类型的输入。你太复杂了。只需去掉非字母数字字符,看看是否有扩展名。
为了进一步分析,您可以订阅许多提供商中的一个,这些提供商将为您提供访问有效数字数据库的权限,并告诉您它们是固定电话还是移动电话、断开连接等。这需要花费资金。
对格式化字符进行替换,然后检查其余字符的电话有效性。在PHP中,
1 2 | $replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num ); |
打破这样复杂的regexp同样有效,但更简单。
我在同一个问题上苦苦挣扎,试图证明我的应用程序的未来,但这些人让我走上了正确的方向。我并不是在检查数字本身,看它是否有效,我只是想确保输入的一系列数字可能有扩展名,也可能没有扩展名。
最坏的情况是,如果用户必须从XML文件中提取一个未格式化的号码,他们仍然只需将这些号码输入手机的数字键盘
1 | \d+ ?\w{0,9} ?\d+ |
01234467 extension 123456 01234567x123456 01234567890
我觉得这很有趣。我还没有测试过,但看起来好像可以用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <?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.'; } ?> |
您最好使用屏蔽输入。这样,用户只能输入数字,您可以根据自己的需要设置格式。我不确定这是否适用于Web应用程序,但是如果是,有一个非常点击jquery插件提供了一些选项。
http://digitalbush.com/projects/masked-input-plugin/
他们甚至在教程中讨论了如何屏蔽电话号码输入。
这里有一个在JavaScript中很好地工作。它在一个字符串中,因为这正是Dojo小部件所期望的。
它匹配一个10位数的北美NANP号码和可选扩展名。空格、短划线和句点是可接受的分隔符。
1 | "^(\\(?\\d\\d\\d\\)?)( |-|\\.)?\\d\\d\\d( |-|\\.)?\\d{4,4}(( |-|\\.)?[ext\\.]+ ?\\d+)?$" |
1 2 | pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" validateat="onsubmit" |
必须以数字结尾,可以以(或+或数字)开头,并且可以包含+-(或)
我的倾向是同意剥去非数字,只接受最好的东西。也许是为了确保至少有几个数字存在,尽管这确实禁止像字母电话号码"ask-jake"这样的事情发生。
几个简单的Perl表达式可能是:
1 2 | @f = /(\d+)/g; tr/0-9//dc; |
使用第一个数字组来保持数字组在一起,这可能会提供格式化的线索。用第二个数字把所有的非数字都轻轻地扔了。
是否担心可能需要暂停,然后输入更多的键?或者像555-1212(等待哔哔声)123?
对于任何想用爱尔兰手机号码做类似事情的人,以下是一个简单的方法:
http://iloviniii.com/?P=87
PHP
1 2 3 4 5 6 | <?php $pattern ="/^(083|086|085|086|087)\d{7}$/"; $phone ="087343266"; if (preg_match($pattern,$phone)) echo"Match"; else echo"Not match"; |
该链接上还有一个jquery解决方案。
编辑:
jquery解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | $(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(); }); }); |
来源。
由于本文没有语言标签,我将给出一个在Python中使用的
表达式本身:
1 | 1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+ |
在python中使用时:
1 2 3 4 5 6 7 | import re phonelist ="1-234-567-8901,1-234-567-8901 1234,1-234-567-8901 1234,1 (234) 567-8901,1.234.567.8901,1/234/567/8901,12345678901" phonenumber = ' '.join([phone for phone in re.findall(r'1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+' ,phonelist)]) print(phonenumber) |
输出:
1 2 3 4 5 6 7 | 1-234-567-8901 1-234-567-8901 1234 1-234-567-8901 1234 1 (234) 567-8901 1.234.567.8901 1/234/567/8901 12345678901 |
我不建议用正则表达式。
和最上面的答案一样,去掉电话号码中所有的丑陋之处,这样,如果提供了扩展名,您就只剩下一串数字字符和一个
在Python中:
注:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | BAD_AREA_CODES = open('badareacodes.txt', 'r').read().split(' ') def is_valid_phone(phone_number, country_code='US'): """for now, only US codes are handled""" if country_code: country_code = country_code.upper() #drop everything except 0-9 and 'x' phone_number = filter(lambda n: n.isdigit() or n == 'x', phone_number) ext = None check_ext = phone_number.split('x') if len(check_ext) > 1: #there's an extension. Check for errors. if len(check_ext) > 2: return False phone_number, ext = check_ext #we only accept 10 digit phone numbers. if len(phone_number) == 11 and phone_number[0] == '1': #international code phone_number = phone_number[1:] if len(phone_number) != 10: return False #area_code: XXXxxxxxxx #head: xxxXXXxxxx #tail: xxxxxxXXXX area_code = phone_number[ :3] head = phone_number[3:6] tail = phone_number[6: ] if area_code in BAD_AREA_CODES: return False if head[0] == '1': return False if head[1:] == '11': return False #any other ideas? return True |
这涵盖了不少。它不是regex,但它很容易映射到其他语言。
以土耳其为例,只需更改
1 | d{9} |
根据你的需要,开始使用它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | function validateMobile($phone) { $pattern ="/^(05)\d{9}$/"; if (!preg_match($pattern, $phone)) { return false; } return true; } $phone ="0532486061"; if(!validateMobile($phone)) { echo 'Incorrect Mobile Number!'; } $phone ="05324860614"; if(validateMobile($phone)) { echo 'Correct Mobile Number!'; } |
是否可以让for-display 4个单独的字段(区号、3位前缀、4位部分、扩展名)以便它们分别输入地址的每个部分,并且您可以分别验证每个部分?这样,您不仅可以使验证更加容易,还可以在数据库中以更一致的格式存储电话号码。
使用简单的regex处理各种国际电话号码几乎是不可能的。
你最好使用一个像numverify.com这样的服务,他们提供了一个免费的JSON API来进行国际电话号码验证,此外,你还可以在每个请求中获得一些关于国家、地点、运营商和线路类型的有用细节。
找到
有助于国际号码。
请注意,它以任何格式输入一个美国移动电话号码,如果您希望输出的移动电话号码的格式看起来漂亮,可以选择接受第二个参数设置为真。如果提供的号码不是移动电话号码,它简单地返回false。如果检测到移动电话号码,它将返回整个已消毒的号码,而不是真的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | function isValidMobile(num,format) { if (!format) format=false var m1 = /^(\W|^)[(]{0,1}\d{3}[)]{0,1}[.]{0,1}[\s-]{0,1}\d{3}[\s-]{0,1}[\s.]{0,1}\d{4}(\W|$)/ if(!m1.test(num)) { return false } num = num.replace(/ /g,'').replace(/\./g,'').replace(/-/g,'').replace(/\(/g,'').replace(/\)/g,'').replace(/\[/g,'').replace(/\]/g,'').replace(/\+/g,'').replace(/\~/g,'').replace(/\{/g,'').replace(/\*/g,'').replace(/\}/g,'') if ((num.length < 10) || (num.length > 11) || (num.substring(0,1)=='0') || (num.substring(1,1)=='0') || ((num.length==10)&&(num.substring(0,1)=='1'))||((num.length==11)&&(num.substring(0,1)!='1'))) return false; num = (num.length == 11) ? num : ('1' + num); if ((num.length == 11) && (num.substring(0,1) =="1")) { if (format===true) { return '(' + num.substr(1,3) + ') ' + num.substr(4,3) + '-' + num.substr(7,4) } else { return num } } else { return false; } } |
尝试此操作(用于印度手机号码验证):
1 2 3 4 5 | if (!phoneNumber.matches("^[6-9]\\d{9}$")) { return false; } else { return true; } |
1 | /\b(\d{3}[^\d]{0,2}\d{3}[^\d]{0,2}\d{4})\b/ |