使用 JavaScript 验证电话号码

Posted

技术标签:

【中文标题】使用 JavaScript 验证电话号码【英文标题】:Validate phone number with JavaScript 【发布时间】:2011-05-19 07:19:30 【问题描述】:

我在某个网站上找到了这段代码,它运行良好。它验证电话号码是以下格式之一:(123) 456-7890123-456-7890

问题是我的客户(我不知道为什么,可能是客户的东西)想要添加另一种格式,连续十个数字,如下所示:1234567890

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

/^(\()?\d3(\))?(-|\s)?\d3(-|\s)\d4$/

如何添加它也验证另一种格式?我不擅长正则表达式。

【问题讨论】:

A comprehensive regex for phone number validation 的可能重复项 根据经验,尝试验证电话号码注定会失败。不同国家和扩展的不同结构是什么,这是一个非常困难的问题。 那么例如法语符号? "12 34 56 78 90" 只需删除除数字以外的所有内容(可能开头的加号除外)并检查长度。 不应该,其实用正则表达式来validate phone numbers properly。 【参考方案1】:

阿根廷数字的正则表达式: /^((+[0-9]1,3))?(([0-9]8,13)|([0-9]3,6)-([0-9 ]4,7))$/

有效:

X:从 8 到 13 个数字 XXXXXXXX 用连字符分隔数字 = X 从 3 到 6; Y:从 4 到 7 XXXX-YYYY Z:从 1 到 3 (+Z)XXXXXXXX 如果您使用 Z 则 (+ ) 是强制性的。

【讨论】:

【参考方案2】:

正则表达式

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

/^[\+]?[(]?[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


【讨论】:

【参考方案3】:

我拿了@marty提供的那个,稍微修改了一下以适应更多的情况:

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

有效格式:

    +1 123 4567890 +11234567890 +1(123)4567890 +1(123)456-7890 +1 (123) 456-7890 +1 (123)456 7890 +1 123 456-7890 +1 123 456 7890 +1 123-456-7890 123-456-7890 123 456-7890 123 456 7890 123 4567890 1234567890

【讨论】:

【参考方案4】:

这个功能对我们很有效:

let isPhoneNumber = input => 

  try 
    let ISD_CODES = [93, 355, 213, 1684, 376, 244, 1264, 672, 1268, 54, 374, 297, 61, 43, 994, 1242, 973, 880, 1246, 375, 32, 501, 229, 1441, 975, 591, 387, 267, 55, 246, 1284, 673, 359, 226, 257, 855, 237, 1, 238, 1345, 236, 235, 56, 86, 61, 61, 57, 269, 682, 506, 385, 53, 599, 357, 420, 243, 45, 253, 1767, 1809, 1829, 1849, 670, 593, 20, 503, 240, 291, 372, 251, 500, 298, 679, 358, 33, 689, 241, 220, 995, 49, 233, 350, 30, 299, 1473, 1671, 502, 441481, 224, 245, 592, 509, 504, 852, 36, 354, 91, 62, 98, 964, 353, 441624, 972, 39, 225, 1876, 81, 441534, 962, 7, 254, 686, 383, 965, 996, 856, 371, 961, 266, 231, 218, 423, 370, 352, 853, 389, 261, 265, 60, 960, 223, 356, 692, 222, 230, 262, 52, 691, 373, 377, 976, 382, 1664, 212, 258, 95, 264, 674, 977, 31, 599, 687, 64, 505, 227, 234, 683, 850, 1670, 47, 968, 92, 680, 970, 507, 675, 595, 51, 63, 64, 48, 351, 1787, 1939, 974, 242, 262, 40, 7, 250, 590, 290, 1869, 1758, 590, 508, 1784, 685, 378, 239, 966, 221, 381, 248, 232, 65, 1721, 421, 386, 677, 252, 27, 82, 211, 34, 94, 249, 597, 47, 268, 46, 41, 963, 886, 992, 255, 66, 228, 690, 676, 1868, 216, 90, 993, 1649, 688, 1340, 256, 380, 971, 44, 1, 598, 998, 678, 379, 58, 84, 681, 212, 967, 260, 263],
      //extract numbers from string
      thenum = input.match(/[0-9]+/g).join(""),
      totalnums = thenum.length,
      last10Digits = parseInt(thenum) % 10000000000,
      ISDcode = thenum.substring(0, totalnums - 10);

    //phone numbers are generally of 8 to 16 digits
    if (totalnums >= 8 && totalnums <= 16) 
      if (ISDcode) 
        if (ISD_CODES.includes(parseInt(ISDcode))) 
          return true;
         else 
          return false;
        
       else 
        return true;
      
    
   catch (e) 

  return false;


console.log(isPhoneNumber('91-9883208806'));

【讨论】:

【参考方案5】:

忽略除数字以外的所有内容。

这是我使用的:

// USA phones should contain at least 10 digits. For Ukrainian phones it's OK to have only 9 digits, without leading 0 and country code prefix: [+380] 88 888-88-88.
String.prototype.isValidPhone = function(digitsCount) 
  var str = this.trim().match(/\d/g);
  return str && str.length >= (digitsCount || 10); // default is at least 10 digits

【讨论】:

【参考方案6】:

试试这个

/^(\+0,)(\d0,)([(]1\d1,3[)]0,)0,(\s ?\d+|\+\d2,3\s1\d+|\d+)1[\s|-]?\d+([\s|-]?\d+)1, 2(\s)0,$/gm

有效格式

(123) 456-7890 (123)456-7890 123-456-7890 1234567890 +31636363634 +3(123) 123-12-12 +3(123)123-12-12 +3(123)1231212 +3(123) 12312123 +3(123) 123 12 12 075-63546725 +7910 120 54 54 910 120 54 54 8 999 999 99 99

https://regex101.com/r/QXAhGV/1

【讨论】:

1 没用,0, 最好写成*。为什么要使用所有这些捕获组?他们减慢了这个过程。 这不好。因为您可以输入任意数量的数字。【参考方案7】:

验证电话号码+返回格式化数据

function validTel(str)
  str = str.replace(/[^0-9]/g, '');
  var l = str.length;
  if(l<10) return ['error', 'Tel number length < 10'];
  
  var tel = '', num = str.substr(-7),
      code = str.substr(-10, 3),
      coCode = '';
  if(l>10) 
    coCode = '+' + str.substr(0, (l-10) );
  
  tel = coCode +' ('+ code +') '+ num;
  
  return ['succes', tel];


console.log(validTel('+1 [223] 123.45.67'));

【讨论】:

【参考方案8】:

此 reg ex 适用于国际电话号码和多种格式的手机号码。

下面是正则表达式: /^(+1\d2,3\s?[(]1\d1,3[)]1\s?\d+|+\d2,3 \s1\d+|\d+)1[\s|-]?\d+([\s|-]?\d+)1,2$/

这里是 javascript 函数

function isValidPhone(phoneNumber) 
    var found = phoneNumber.search(/^(\+1\d2,3\s?[(]1\d1,3[)]1\s?\d+|\+\d2,3\s1\d+|\d+)1[\s|-]?\d+([\s|-]?\d+)1,2$/);
    if(found > -1) 
        return true;
    
    else 
        return false;
    

这会验证以下格式:

+44 07988-825 465(用连字符的任意组合代替空格,除了 +44 后面必须只有一个空格)

+44 (0) 7988-825 465(用连字符的任意组合代替空格,但 (0) 之前或之后不能直接存在连字符并且 (0) 之前或之后的空格不必存在)

123 456-789 0123(用连字符的任意组合代替空格)

123-123 123(用连字符的任意组合代替空格)

123 123456(空格可以用连字符代替)

1234567890

所有格式都不能存在双空格或双连字符。

【讨论】:

这验证了 123 是有效的【参考方案9】:

试试这个

/^[\+]?\d2,?[(]?\d2,[)]?[-\s\.]?\d2,?[-\s\.]?\d2,[-\s\.]?\d0,9$/im

有效格式:

    (123) 456-7890 (123)456-7890 123-456-7890 123.456.7890 1234567890 +31636363634 +3(123) 123-12-12 +3(123)123-12-12 +3(123)1231212 +3(123) 12312123 075-63546725

【讨论】:

请确保在您的回答中包含解释。尽管它可能有效,但重要的是要解释如何以及为什么以获得完整和相关的信息。感谢您的回答:)【参考方案10】:

试试这个js函数。 如果匹配则返回 true,如果失败则返回 false Ref

function ValidatePhoneNumber(phone) 
        return /^\+?([0-9]2)\)?[-. ]?([0-9]4)[-. ]?([0-9]4)$/.test(phone);

【讨论】:

【参考方案11】:

/^\+?1?\s*?\(?\d3(?:\)|[-|\s])?\s*?\d3[-|\s]?\d4$/

虽然这篇文章很老但是想留下我的贡献。 这些被接受: 5555555555 555-555-5555 (555)555-5555 1(555)555-5555 1 555 555 5555 1 555-555-5555 1 (555) 555-5555

这些不被接受:

555-5555 -> 接受此用途:^\+?1?\s*?\(?(\d3)?(?:\)|[-|\s])?\s*?\d3[-|\s]?\d4$

5555555 -> 接受此用途:^\+?1?\s*?\(?(\d3)?(?:\)|[-|\s])?\s*?\d3[-|\s]?\d4$

1 555)555-5555 123**&!!asdf# 55555555 (6505552368) 2 (757) 622-7382 0 (757) 622-7382 -1 (757) 622-7382 2 757 622-7382 10 (757) 622-7382 27576227382 (275)76227382 2(757)6227382 2(757)622-7382 (555)5(55?)-5555

这是我使用的代码:

function telephoneCheck(str) 
  var patt = new RegExp(/^\+?1?\s*?\(?\d3(?:\)|[-|\s])?\s*?\d3[-|\s]?\d4$/);
  return patt.test(str);


telephoneCheck("+1 555-555-5555");

【讨论】:

这个正则表达式的唯一问题是它认为有效的电话字符串只有一个 ')' 或只有一个 '(' (如“(555-555-5555”))【参考方案12】:

很简单

"9001234567".match(/^\d10$/g)

【讨论】:

【参考方案13】:
\\(?\d3\\)?([\-\s\.])?\d3\1?\d4

这将验证任何可变格式的电话号码:

\\(?\d3\\)? 查找用括号括起来的 3 位数字。

([\-\s\.])? 是否找到这些分隔符中的任何一个

\d3 找到 3 个数字

\1 使用第一个匹配的分隔符 - 这确保分隔符相同。因此 (000) 999-5555 将不会在此处验证,因为存在空格和破折号分隔符,因此只需删除“\1”并替换为分隔符子模式(这样做也会验证非标准格式)。但是,无论如何您都应该对用户输入进行格式提示。

\d4 找到 4 位数字

验证:

(000) 999 5555 (000)-999-5555 (000).999.5555 (000) 999-5555 (000)9995555 000 999 5555 000-999-5555 000.999.5555 0009995555

顺便说一句,这是针对 JavaScript 的,因此是双重转义。

【讨论】:

【参考方案14】:

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

/^[+]?(1\-|1\s|1|\d3\-|\d3\s|)?((\(\d3\))|\d3)(\-|\s)?(\d3)(\-|\s)?(\d4)$/g

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

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

【讨论】:

【参考方案15】:

只是想添加一个专门用于选择非本地电话号码(800 和 900 类型)的解决方案。

(\+?1[-.(\s]?|\()?(900|8(0|4|5|6|7|8)\3+)[)\s]?[-.\s]?\d3[-.\s]?\d4

【讨论】:

【参考方案16】:

简单正则表达式:/\b\d3[-.]?\d3[-.]?\d4\b/g

检查格式,希望它有效: 444-555-1234 传真:246.555.8888 手机:1235554567

【讨论】:

请格式化您的答案(使用四个空格作为代码块的缩进)。对代码的解释也将提高其质量。【参考方案17】:

我选择的正则表达式是:

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

有效格式:

(123) 456-7890(123)456-7890123-456-7890123.456.78901234567890+31636363634075-63546725

【讨论】:

什么是 /im ?在谷歌上找不到解释:) @SarinSuriyakoon i 使表达式不区分大小写,m 执行多行搜索 为什么数字需要不区分大小写? 这个正则表达式很棒,因为如果你删除开头的^ 和结尾的$,它也可以在字符串中间找到电话号码 @darioxlz '123456789' 不是电话号码的有效长度【参考方案18】:

如果您使用输入标签,则此代码将对您有所帮助。我自己编写了这段代码,我认为这是在输入中使用的非常好的方法。但您可以使用您的格式更改它。它将帮助用户更正输入标签的格式。

$("#phone").on('input', function()   //this is use for every time input change.
        var inputValue = getInputValue(); //get value from input and make it usefull number
        var length = inputValue.length; //get lenth of input

        if (inputValue < 1000)
        
            inputValue = '1('+inputValue;
        else if (inputValue < 1000000) 
        
            inputValue = '1('+ inputValue.substring(0, 3) + ')' + inputValue.substring(3, length);
        else if (inputValue < 10000000000) 
        
            inputValue = '1('+ inputValue.substring(0, 3) + ')' + inputValue.substring(3, 6) + '-' + inputValue.substring(6, length);
        else
        
            inputValue = '1('+ inputValue.substring(0, 3) + ')' + inputValue.substring(3, 6) + '-' + inputValue.substring(6, 10);
               
        $("#phone").val(inputValue); //correct value entered to your input.
        inputValue = getInputValue();//get value again, becuase it changed, this one using for changing color of input border
       if ((inputValue > 2000000000) && (inputValue < 9999999999))
      
          $("#phone").css("border","black solid 1px");//if it is valid phone number than border will be black.
      else
      
          $("#phone").css("border","red solid 1px");//if it is invalid phone number than border will be red.
      
  );

    function getInputValue() 
         var inputValue = $("#phone").val().replace(/\D/g,'');  //remove all non numeric character
        if (inputValue.charAt(0) == 1) // if first character is 1 than remove it.
        
            var inputValue = inputValue.substring(1, inputValue.length);
        
        return inputValue;

【讨论】:

【参考方案19】:

我会做的是忽略格式并验证数字内容:

var originalPhoneNumber = "415-555-1212";

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

【讨论】:

同意忽略格式,例如手机号码通常带有空格,如 XXXX XXX XXX,但表单要求输入不带空格,即 XXXXXXXXXX。【参考方案20】:

其中 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|)?((\(\d3\))|\d3)(\-|\s)?(\d3)(\-|\s)?(\d4)$/.test(str);
  alert(isphone);

telephoneCheck("1 555 555 5555");

【讨论】:

不错的正则表达式,这是这个问题的最佳答案【参考方案21】:
/^[+]*[(]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

【讨论】:

正则表达式稍作修改以允许例如+41 (79) 123 45 67(瑞士):/^[+]?[\s./0-9]*[(]?[0-9]1,4[)]?[-\s./0-9]*$/g 这个似乎很适合我,因为它不是太字符串而且似乎涵盖了所有国际格式(感谢@RemigiusStalder 对瑞士的修复) 如果你有java后端,你可以添加电话号码规范化,例如来自github.com/google/libphonenumber 最好加个字数限制。用 [8, 14] 更改最后一个 *(星号):/^[+]*[(]0,1[0-9]1,3[)]0,1[-\s\./0-9]8,14$/g【参考方案22】:

首先,您的格式验证器显然只适用于NANP(国家代码+1)数字。电话号码来自北美以外的人是否会使用您的应用程序?如果是这样,您不想阻止这些人输入完全有效的 [国际] 号码。

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

因此,您的正则表达式将传递号码 (123) 123 4566,即使该号码不是有效的电话号码。您可以通过将\d3 替换为[2-9]1\d2 来解决此问题。

最后,我感觉您正在验证网络浏览器中的用户输入。请记住,客户端验证是only a convenience you provide to the user;您仍然需要(再次)验证服务器上的所有输入。

TL;DR 不要对validate complex real-world data like phone numbers 或URLs 使用正则表达式。使用specialized library。

【讨论】:

我同意正则表达式不足以验证电话号码,因为电话号码计划实际上是基于范围工作的,例如12300000 至 12399999 (numberingplans.com/…) 问题是在前端应用中捆绑 libphonenumber 需要 >500Kb。 (bundlephobia.com/package/google-libphonenumber@3.2.22) 我认为如果您想进行电话号码验证,这是一个很好的起点:github.com/google/libphonenumber/blob/master/FALSEHOODS.md 考虑到复杂性,我也会考虑使用专门的在线服务,例如:validatephonenumber.com【参考方案23】:

如果您要查找 10 位且只有 10 位数字,请忽略除数字之外的所有内容-

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

【讨论】:

这就是我要建议的。轻松活泼的。无论如何,过多的验证可能是一件坏事。 这是最好的方法。除非你真的很在意它的格式,否则这一切都是为了确保数字是部分有效的,而不是一堆乱七八糟的东西。 你的意思是匹配(/\d/g)不匹配(/\d/)或者长度为1,而不是10;此外,空字符串的匹配项为空。至少它应该是 var m = value.match(/\d/g);返回 m && m.length === 10 return (value.match(/\d/g) || []).length == 10 或更简单(但同样有缺陷):return value.replace(/\D/g,'').length == 10 我喜欢这个:/\D/gi.test(value)。不是数字的所有内容,包括空格、破折号等......【参考方案24】:

每个人的答案都很棒,但这里有一个我认为更全面的...

这是为 javascript 匹配在单行中使用单个数字而编写的:

^(?!.*911.*\d4)((\+?1[\/ ]?)?(?![\(\. -]?555.*)\( ?[2-9][0-9]2 ?\) ?|(\+?1[\.\/ -])?[2-9][0-9]2[\.\/ -]?)(?!555.?01..)([2-9][0-9]2)[\.\/ -]?([0-9]4)$

如果你想在单词边界匹配,只需将 ^ 和 $ 更改为 \b

我欢迎对此解决方案提出任何建议、更正或批评。据我所知,这与 NANP 格式相匹配(对于美国号码 - 创建此号码时我没有验证其他北美国家),避免任何 911 错误(不能在区号或地区代码中),消除只有那些实际无效的 555 个数字(区域代码 555 后跟 01xx,其中 x = 任意数字)。

【讨论】:

【参考方案25】:

以下 REGEX 将验证任何这些格式:

(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$/

【讨论】:

您需要转义 . 否则它将匹配任意字符,从而破坏您的正则表达式。 这使我朝着正确的方向前进。谢谢!不幸的是,这个表达式也将匹配 (1234567890 和 123)4567890。 ^((([0-9]3))|([0-9]3))[-\s\.]?[0-9]3[-\s\.]? [0-9]4$ 解决了这个小问题。【参考方案26】:

我不得不承认验证电话号码是一项艰巨的任务。 至于这个具体问题,我会从

更改正则表达式
/^(()?\d3())?(-|\s)?\d3(-|\s)\d4$/

/^(()?\d3())?(-|\s)?\d3(-|\s)?\d4$/

唯一不需要的元素是最后一个破折号/空格。

【讨论】:

我真的在努力提升我的正则表达式游戏!我正在使用“正则表达式教练”检查您的建议。我正在使用正则表达式 (()?\d3())?(-|\s)?\d3(-|\s)?\d4 和目标字符串 (123) 456-7890 但由于某种原因它只抓取最后 7 位数字。有什么想法吗? 是的,正则表达式对大脑有点粗糙......和耐心。好的试试 /^[(]?(\d3)[)]?[-|\s]?(\d3)[-|\s]?(\d4)$/旧正则表达式的第一部分表现不佳: "(()?\d3())" (() 中间括号实际上被视为正则表达式语法的一部分,而不是要查找的字符。 【参考方案27】:

/^(()?\d3())?(-|\s)?\d3(-|\s)?\d4$/

? 字符表示前面的组应该匹配零次或一次。 (-|\s) 组将匹配 -| 字符。

【讨论】:

【参考方案28】:

我建议使用更清晰的东西(尤其是考虑谁必须维护代码)......怎么样:

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

正则表达式是从一个清晰的模板构建的?然后添加一个新的就很容易了,甚至客户自己也可以在“选项”页面中做到这一点。

【讨论】:

【参考方案29】:

这将起作用:

/^(()?\d3())?(-|\s)?\d3(-|\s)?\d4$/

? 字符表示前面的组应该匹配零次或一次。 (-|\s) 组将匹配 -| 字符。在您的正则表达式中第二次出现此组之后添加? 允许您匹配10 个连续数字的序列。

【讨论】:

以上是关于使用 JavaScript 验证电话号码的主要内容,如果未能解决你的问题,请参考以下文章

关于 JavaScript 中电话号码的表单验证问题

如何使用 javascript 从 Firebase 电话身份验证中删除验证码?

JavaScript表单通过正则表达式验证电话号码

javascript编写验证电话号码的完整代码

javascript身份证号码验证

身份证号码的正则表达式及验证详解(JavaScript,Regex)