我试图把一个全面的正则表达式放在一起来验证电话号码。理想情况下,它可以处理国际格式,但它必须处理美国格式,包括以下内容:
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 1-234-567-8901 x1234 1-234-567-8901 ext1234 1 (234) 567-8901 1.234.567.8901 1/234/567/8901 12345678901
我会用我目前的尝试来回答,但我希望有人有更好的和/或更优雅的东西。
当前回答
我在另一个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
其他回答
由于这篇文章没有语言标签,我将给出一个在python中使用的正则表达式解决方案。
表达式本身:
1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+
在python中使用时:
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 = '\n'.join([phone for phone in re.findall(r'1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+' ,phonelist)])
print(phonenumber)
输出:
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
执行替换格式化字符,然后检查剩余的电话有效性。在PHP中,
$replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed
preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );
打破像这样复杂的regexp同样有效,但要简单得多。
我在一家市场研究公司工作,我们必须一直过滤这些类型的输入。你把事情复杂化了。去掉非字母数字字符,看看是否有扩展。
为了进一步分析,你可以订阅众多提供商中的一家,这些提供商会让你访问有效号码数据库,并告诉你他们是座机还是移动电话,断开连接等等。这需要花钱。
这是一个简单的菲律宾手机号码的正则表达式模式:
((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}
or
((\+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
如果讨论的是表单验证,那么验证正确含义和正确数据的regexp将非常复杂,因为不同国家和提供者的标准各不相同。它也很难跟上时代。
我把这个问题解释为寻找一个广泛有效的模式,这个模式可能在内部不一致——例如,拥有一组有效的数字,但不验证中干线、交换机等与国家代码前缀的有效模式是否一致。
北美是简单明了的,而在国际上,我更喜欢使用一种“惯用”模式,即人们指定和记忆数字的方式:
^((((\(\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 1 1234 123456 x12345 +12 1234 1234 +12 12 1234 +12 1234 5678 + 12 12345678
这可能有偏见,因为我的经验仅限于北美、欧洲和一小部分亚洲。