使用JavaScript验证手机号码

233
我在某个网站上找到了这段代码,它可以完美地验证电话号码是否为以下格式之一:
(123) 456-7890123-456-7890

问题是我的客户(我不知道为什么,可能是客户的事情)想要添加另一种格式,即连续十个数字,类似于这样:1234567890

我正在使用这个正则表达式:

/^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/

我该如何添加验证另一种格式的代码?我不擅长正则表达式。


3
可能是 A comprehensive regex for phone number validation 的重复问题。 - Alex Wayne
7
作为一个经验法则——尝试验证电话号码注定会失败。由于不同国家有不同的结构和扩展,这是一个非常棘手的问题。 - Quentin
3
那么对于例如法国的记法呢?“12 34 56 78 90”,只需移除除数字以外的所有内容(除了开头的加号),并检查长度即可。 - thejh
实际上,您不应该使用正则表达式来正确验证电话号码 - Dan Dascalescu
30个回答

251

我选择的正则表达式是:

/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im

有效格式:

(123) 456-7890
(123)456-7890
123-456-7890
123.456.7890
1234567890
+31636363634
075-63546725


7
"/im" 是什么?在 Google 上找不到解释 :) - Sarin Suriyakoon
11
@SarinSuriyakoon:i可以使表达式不区分大小写,而m可以执行多行搜索。 - Rodrigo Leite
76
为什么需要对数字不区分大小写? - Solomon Closson
1
这个正则表达式很棒,因为如果你在开头删除 ^ 和结尾的 $,它也可以在字符串中间找到电话号码。 - hobberwickey
3
“123456789”不是一个有效的电话号码长度。 - punjabi4life
显示剩余7条评论

156

首先,你的格式验证器显然只适用于NANP(国家代码+1)号码。你的应用程序将由来自北美以外地区的用户使用吗?如果是,你不希望阻止这些人输入完全有效的[国际]号码。

其次,你的验证是不正确的。NANP号码采用NXX NXX XXXX的形式,其中N是数字2-9,X是数字0-9。此外,区号和交换机不能采用N11的形式(以两个“1”结尾),以避免与特殊服务混淆,除了非地理区号(800、888、877、866、855、900)的号码可以具有N11交换机。

因此,你的正则表达式将通过号码(123) 123 4566,即使那不是一个有效的电话号码。你可以通过将\d{3}替换为[2-9]{1}\d{2}来解决这个问题。

最后,在我看来,你正在web浏览器中验证用户输入。请记住,客户端验证只是你提供给用户的便利;你仍然需要在服务器上重新验证所有输入。

简而言之:不要使用正则表达式来验证复杂的真实世界数据,如电话号码URLs。使用专门的库


我同意正则表达式并不足以验证电话号码,因为电话编码计划实际上是基于范围的,例如12300000到12399999(http://www.numberingplans.com/?page=plans&sub=phonenr&alpha_2_input=US&current_page=15242) - user591593
问题在于将libphonenumber捆绑到前端应用程序中需要> 500Kb。(https://bundlephobia.com/package/google-libphonenumber@3.2.22)如果您想开始进行电话号码验证,我认为这是一个很好的起点:https://github.com/google/libphonenumber/blob/master/FALSEHOODS.md考虑到复杂性,我还会考虑使用专门的在线服务,例如:https://validatephonenumber.com/ - dsdenes

82

如果您只需要查找 10 个数字,那么忽略除数字以外的所有内容 -

   return value.match(/\d/g).length===10;

这就是我要建议的。轻松愉快。而且过多的验证也可能是件坏事。 - mwilcox
1
这是最好的方法。除非你真的关心它的格式,否则所有这些只是确保数字部分有效,而不是一堆胡言乱语。 - mdance
10
你的意思是使用match(/\d/g)而非match(/\d/),否则长度为1而非10;同时,对于空字符串的匹配结果为null。至少应该使用var m = value.match(/\d/g); return m && m.length === 10来确保正确性。 - Doug
或者使用更简单但同样有缺陷的代码:return value.replace(/\D/g,'').length == 10,其中 \D 匹配非数字字符。 - RobG
我喜欢这个:/\D/gi.test(value)。 包括空格、破折号等在内的所有非数字字符... - Gus

52
/^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]*$/g

(123) 456-7890
+(123) 456-7890
+(123)-456-7890
+(123) - 456-7890
+(123) - 456-78-90
123-456-7890
123.456.7890
1234567890
+31636363634
075-63546725

这是一种非常灵活的选择,我更喜欢保持它原来的方式,因为我通常在注册表单中使用它,用户需要添加他们的电话号码。 通常情况下,用户会对强制执行严格格式规则的表单感到困惑,我更喜欢让用户填写号码,然后在显示之前或保存到数据库之前进行格式化。 http://regexr.com/3c53v


8
正则表达式略作修改,以支持例如 +41 (79) 123 45 67(瑞士):/^[+]?[\s./0-9]*[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/g - Remigius Stalder
这个看起来很适合我,因为它不太严格,似乎涵盖了所有的国际格式(感谢@RemigiusStalder提供的瑞士修复)。 - Gavin
如果您有Java后端,您可以添加电话号码归一化,例如从https://github.com/google/libphonenumber。 - Remigius Stalder
3
最好添加字符限制。将最后一个*(星号)更改为[8,14]:/^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]{8,14}$/g - kuzey beytar

36

我会忽略格式,而验证数字内容:

var originalPhoneNumber = "415-555-1212";

function isValid(p) {
  var phoneRe = /^[2-9]\d{2}[2-9]\d{2}\d{4}$/;
  var digits = p.replace(/\D/g, "");
  return phoneRe.test(digits);
}

1
同意忽略格式,例如手机号码通常会带有空格,如XXXX XXX XXX,但表单要求输入时不需要空格,即XXXXXXXXXX。 - RobG

33

以下正则表达式可以验证下列任意格式:

(123) 456-7890
123-456-7890
123.456.7890
1234567890

/^[(]{0,1}[0-9]{3}[)]{0,1}[-\s\.]{0,1}[0-9]{3}[-\s\.]{0,1}[0-9]{4}$/

3
你需要转义 .,否则它将匹配任意字符,使你的正则表达式失效。 - Christoph
2
这让我朝着正确的方向前进。谢谢!不幸的是,这个表达式也会匹配(1234567890和123)4567890。 ^((([0-9]{3}))|([0-9]{3}))[-\s.]?[0-9]{3}[-\s.]?[0-9]{4}$解决了这个小问题。 - Joe Hawkins

24

str可以是以下任何一种格式:

555-555-5555 (555)555-5555 (555) 555-5555 555 555 5555 5555555555 1 555 555 5555

function telephoneCheck(str) {
  var isphone = /^(1\s|1|)?((\(\d{3}\))|\d{3})(\-|\s)?(\d{3})(\-|\s)?(\d{4})$/.test(str);
  alert(isphone);
}
telephoneCheck("1 555 555 5555");


不错的正则表达式,这是对这个问题最好的答案。 - JoelBonetR

20

我建议使用更加清晰的方式(尤其是考虑到谁将来会维护这段代码)......怎么样:

var formats = "(999)999-9999|999-999-9999|9999999999";
var r = RegExp("^(" +
               formats
                 .replace(/([\(\)])/g, "\\$1")
                 .replace(/9/g,"\\d") +
               ")$");

正则表达式是从一个清晰的模板构建的吗?这样添加新的正则表达式将变得非常简单,甚至客户自己也能够在“选项”页面上完成。


11

试试这个 - 它还包括国际格式的验证。

/^[+]?(1\-|1\s|1|\d{3}\-|\d{3}\s|)?((\(\d{3}\))|\d{3})(\-|\s)?(\d{3})(\-|\s)?(\d{4})$/g

此正则表达式验证以下格式:

  • (541) 754-3010 美国国内
  • +1-541-754-3010 国际
  • 1-541-754-3010 在美国拨打
  • 001-541-754-3010 从德国拨打
  • 191 541 754 3010 从法国拨打

10

正则表达式

使用以下正则表达式模式:

/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im

像这样:<input pattern="/^ [\+] ? [(] ? [0-9]{3} [)] ? [-\s\.]?[0-9]{3} [-\s\.]?[0-9]{4,6}$/im">*


有效格式:

(123) 456-7890,
(123)456-7890,
123-456-7890,
123.456.7890,
1234567890,
+31636363634或
075-63546725



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接