我试图把一个全面的正则表达式放在一起来验证电话号码。理想情况下,它可以处理国际格式,但它必须处理美国格式,包括以下内容:
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
我会用我目前的尝试来回答,但我希望有人有更好的和/或更优雅的东西。
当前回答
在阅读了这些答案之后,似乎没有一个简单的正则表达式可以解析一堆文本并提取任何格式的电话号码(包括带加号和不带加号的国际电话号码)。
这是我最近在一个客户项目中使用的,我们必须将任何格式的所有电话号码转换为tel: links。
到目前为止,它可以处理他们抛出的所有问题,但如果出现错误,我会更新这个答案。
正则表达式:
/ (1 + * % d ( ,})*([ |\(])*(\ 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})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
return $return;
}
其他回答
既然写电话号码有很多选择, 我们可以测试其中有足够的数字,不管它们是如何分开的。我发现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,}
(如果没有上限,则不需要^$)
在阅读了这些答案之后,似乎没有一个简单的正则表达式可以解析一堆文本并提取任何格式的电话号码(包括带加号和不带加号的国际电话号码)。
这是我最近在一个客户项目中使用的,我们必须将任何格式的所有电话号码转换为tel: links。
到目前为止,它可以处理他们抛出的所有问题,但如果出现错误,我会更新这个答案。
正则表达式:
/ (1 + * % d ( ,})*([ |\(])*(\ 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})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
return $return;
}
我不建议使用正则表达式。
和上面的答案一样,去掉所有难看的电话号码,这样你就只剩下一串数字字符,如果提供扩展名的话,还会有一个'x'。
在Python中:
注意:BAD_AREA_CODES来自一个文本文件,您可以从web上获取。
BAD_AREA_CODES = open('badareacodes.txt', 'r').read().split('\n')
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
这涵盖了相当多的内容。它不是一个正则表达式,但它确实很容易映射到其他语言。
我在一家市场研究公司工作,我们必须一直过滤这些类型的输入。你把事情复杂化了。去掉非字母数字字符,看看是否有扩展。
为了进一步分析,你可以订阅众多提供商中的一家,这些提供商会让你访问有效号码数据库,并告诉你他们是座机还是移动电话,断开连接等等。这需要花钱。
注意:它以任何格式的美国手机号码作为输入,并可选地接受第二个参数-如果您希望输出的手机号码格式看起来更漂亮,则设置为true。如果提供的号码不是移动电话号码,则简单地返回false。如果检测到一个移动号码,它将返回整个经过消毒的号码,而不是true。
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;
}
}