我试图把一个全面的正则表达式放在一起来验证电话号码。理想情况下,它可以处理国际格式,但它必须处理美国格式,包括以下内容:
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
我会用我目前的尝试来回答,但我希望有人有更好的和/或更优雅的东西。
当前回答
如果讨论的是表单验证,那么验证正确含义和正确数据的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
这可能有偏见,因为我的经验仅限于北美、欧洲和一小部分亚洲。
其他回答
我在另一个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
这是我目前为止最好的尝试。它处理上面的格式,但我确信我错过了一些其他可能的格式。
^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$
虽然它不是正则表达式,但您可以使用Python库DataPrep中的validate_phone()函数来验证美国电话号码。使用pip Install dataprep安装它。
>>> from dataprep.clean import validate_phone
>>> df = pd.DataFrame({'phone': ['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, '12345678', '123-456-78987']})
>>> validate_phone(df['phone'])
0 True
1 True
2 True
3 True
4 True
5 True
6 True
7 False
8 False
Name: phone, dtype: bool
你看过RegExLib了吗?
输入一个美国的电话号码,你会发现很多可能性。
如果讨论的是表单验证,那么验证正确含义和正确数据的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
这可能有偏见,因为我的经验仅限于北美、欧洲和一小部分亚洲。