电话号码正则表达式所有格式

时间:2018-08-13 19:19:34

标签: python regex

我正在开发一个表达式,以验证所有可能的电话号码格式。我有50%,它不是通过* . - whitespace

来验证我所接受的字符

这些是规则

  

它可以包含左括号和右括号。 (55)

     

它可以继续或不继续'+​​'char ex。 (+52)

     

在括号ex内可以包含2或3个数字。 (+555)o(+55)

     

它可以在右括号和下一个括号之间包含空格   数字前(55)44332211

     

括号中的连续数字必须是6或8个数字。   (55)443322 o(55)44332211

     

括号中的连续数字可以包含空格,   破折号,星号或冒号。例如(55)44-33-22-11 o(55)44 33 22 11 o   (55)44 * 33 * 22 * 11 o(55)44.33.22.11

     

括号中的连续数字可以分为   例如2、3或4个数字(55)5544-3322 o(55)55 44 33 22 o(555)444 * 333

     

数字格式可以排成8个,例如10 o 12个数字。 55443322   o 5544332211 o 554433221100

这是正则表达式

[\(]?[\+]?(\d{2}|\d{3})[\)]?[\s]?((\d{6}|\d{8})|(\d{3}[\*\.\-\s]){3}|(\d{2}[\*\.\-\s]){4}|(\d{4}[\*\.\-\s]){2})|\d{8}|\d{10}|\d{12}

这是正则表达式的映射 enter image description here

我在做什么错?我留下一个示例脚本,即我为Python做的正则表达式,我不知道我是否对JS进行了很多改动

$(function(){

  $('ul li').each(function(){
    let number = $(this).text();
    let regex = /^[\(]?[\+]?(\d{2}|\d{3})[\)]?[\s]?((\d{6}|\d{8})|(\d{3}[\*\.\-\s]){3}|(\d{2}[\*\.\-\s]){4}|(\d{4}[\*\.\-\s]){2})|\d{8}|\d{10}|\d{12}$/;
    let res = regex.test( number );
    $(this).text( $(this).text() + ' is: ' + res);
  });

})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Telephone numbers
<ul>
  <li>test</li>
  <li>(55)test</li>
  <li>(55)333-test</li>
  <li>(55)test 22</li>
  <li>554433221100</li>
  <li>5544332211</li>
  <li>55443322</li>
  <li>(55)443322</li>
  <li>(55)44332211</li>
  <li>(+55)443322</li>
  <li>(+55)44332211</li>
  <li>(55)4433*2211</li>
  <li>(55)444.333</li>
  <li>(55)44-33-22-11</li>
  <li>(55)4433-2211</li>
  <li>(+55)443 322</li>
</ul>

3 个答案:

答案 0 :(得分:2)

您可以使用

^(?:\d{8}(?:\d{2}(?:\d{2})?)?|\(\+?\d{2,3}\)\s?(?:\d{4}[\s*.-]?\d{4}|\d{3}[\s*.-]?\d{3}|\d{2}([\s*.-]?)\d{2}\1\d{2}(?:\1\d{2})?))$

请参见regex demo

详细信息

  • ^-字符串的开头
  • (?:-外部分组构造的开始:
    • \d{8}-8位数字
    • (?:\d{2}(?:\d{2})?)?-可选的2位数字,后跟可选的2位数字子字符串(因此,可以匹配8、10或12位数字的字符串)
  • |-或

    • \(-一个(
    • \+?-1或0加号
    • \d{2,3}-2或3位数字
    • \)-一个)字符
    • \s?-1或0个空格
    • (?:-分组:
      • \d{4}-4位数字
      • [\s*.-]?-空格*.-,可选出现
      • \d{4}-4位数字
    • |-或
      • \d{3}[\s*.-]?\d{3}-3位数字,一个定界符char,3位数字
    • |-或

      • \d{2}([\s*.-]?)\d{2}\1\d{2}(?:\1\d{2})?:2位数字,捕获到第1组中的分隔符,两位数,与第1组中的相同分隔符,两位数,以及与第1组和第2位相同的分隔符char的可选序列
    • )-内部分组的结尾。

  • )-外部分组的结尾
  • $-字符串的结尾。

答案 1 :(得分:0)

另一种可能的解决方案(可能更简单)是在来源处简单地验证电话号码,然后仅在服务器端允许这种格式。

(function(){
  "use strict";
  var removeNonPhoneNumber = /\D/g;

  function formatPhoneNumber(ownSection, restOfIt){
    var newOwnSection = ownSection.replace(removeNonPhoneNumber, "");
    var newRestOfIt = restOfIt.replace(removeNonPhoneNumber, "");
    var totalLength = newOwnSection.length + restOfIt.length |0;

    var i=0, res="";
    if (totalLength > 10) {
      // includes country code
      for (; i < (totalLength - 10|0) && i < newOwnSection.length; i=i+1|0)
        res += newOwnSection.charAt(i);
      res += '-';
    }
    if (totalLength > 7) {
      // includes area code
      for (; i < (totalLength - 7|0) && i < newOwnSection.length; i=i+1|0)
        res += newOwnSection.charAt(i);
      res += '-';
    }
    if (totalLength > 4) {
      // includes local code
      for (; i < (totalLength - 4|0) && i < newOwnSection.length; i=i+1|0)
        res += newOwnSection.charAt(i);
      res += '-';
    }
    for (; i < totalLength && i < newOwnSection.length; i=i+1|0)
      res += newOwnSection.charAt(i);
    return res;
  }
  function autoStretch(evt){
    var target = evt && evt.target;
    if (!target) return;
    if (
      target.getAttribute("type") === "tel" && (
        // If selectionStart is supported OR the user is deselecting
          // the input, then validate
        typeof target.selectionStart === "number" ||
        evt.type === "blur"
      )
    ) {
      // forceful tel validation. It normalizes the number to be pretty
      var valueNow = target.value;
      var sStart=target.selectionStart|0, sEnd=target.selectionEnd|0;

      var newValue = formatPhoneNumber(valueNow, "");
      if (valueNow !== newValue) {
        target.value = newValue;

        // now properly shift around the cursor positions:
        if(typeof target.selectionStart==="number") 
          target.selectionStart = formatPhoneNumber(
            valueNow.substring(0, sStart), valueNow.substring(sStart)
          ).length|0;
        if(typeof target.selectionEnd==="number") 
          target.selectionEnd = formatPhoneNumber(
            valueNow.substring(0, sEnd), valueNow.substring(sEnd)
          ).length|0;
      }
    }
    target.style.width = '';
    target.style.width = target.scrollWidth + 'px';
  }

  var teleInputs = document.getElementsByClassName("prevent-invalid-telephone");
  for (var i=0, hookOptions={"passive":1}; i<teleInputs.length; i=i+1|0) {
    teleInputs[i].addEventListener("input", autoStretch, hookOptions);
    teleInputs[i].addEventListener("change", autoStretch, false);//for IE
  }
})();
Enter your telephone here: <input type="tel" autocomplete="tel-area-code" pattern="([0-9]+-)?[0-9]{3}-[0-9]{3}-[0-9]{4}" aria-label="Your telephone number" class="prevent-invalid-telephone"/>

上面的代码片段看起来很长,但请放心,压缩后它会减少到仅1008字节(应用zopfli gzip后仅486字节)。

!function(){"use strict";function h(c,b){var d=c.replace(/\D/g,"")
b.replace(/\D/g,"");var e=d.length+b.length|0,a=0,f=""
if(10<e){for(;a<(e-10|0)&&a<d.length;a=a+1|0)f+=d.charAt(a)
f+="-"}if(7<e){for(;a<(e-7|0)&&a<d.length;a=a+1|0)f+=d.charAt(a)
f+="-"}if(4<e){for(;a<(e-4|0)&&a<d.length;a=a+1|0)f+=d.charAt(a)
f+="-"}for(;a<e&&a<d.length;a=a+1|0)f+=d.charAt(a);return f}function
l(c){var b=c&&c.target;if(b){if("tel"===b.getAttribute("type")&&("number"==typeof
b.selectionStart||"blur"===c.type)){c=b.value;var
d=b.selectionStart|0,e=b.selectionEnd|0,a=h(c,"")
c!==a&&(b.value=a,"number"==typeof b.selectionStart&&(b.selectionStart=h(
c.substring(0,d),c.substring(d)).length|0),"number"==typeof
b.selectionEnd&&(b.selectionEnd=h(c.substring(0,e),c.substring(e)).length|0))}
b.style.width="";b.style.width=b.scrollWidth+"px"}}for(var
k=document.getElementsByClassName("prevent-invalid-telephone"),g=0;g<k.length;g=g+1|0)
k[g].addEventListener("input",l,{passive:1}),k[g].addEventListener("change",l,!1)}();
Enter your telephone here: <input type="tel" autocomplete="tel-area-code" pattern="([0-9]+-)?[0-9]{3}-[0-9]{3}-[0-9]{4}" aria-label="Your telephone number" class="prevent-invalid-telephone"/>

答案 2 :(得分:0)

接受的答案有很多缺陷:

  • \s 不仅适用于空白字符,还适用于 \r 和 \n。

    +11 1111
    1111
    #This matches
    
  • 一个号码的最小位数为 8 位,最大位数为 12 位,但这些数字与国际前缀数字无关:

    (+39)333 333 # 6 digits: this matches but it is not valid  
    (+39)3333 3333 3333 # 12 digits: this is valid but it does not match
    
  • 国际前缀只在括号之间匹配

    +39 3475 4087 18 # this is valid but doesn't match
    
  • 正则表达式并不是无缘无故的琐碎、冗长、复杂和窃听。

我制作这个是为了克服这些缺陷并改进它:

^(?:((\+?\d{2,3})|(\(\+?\d{2,3}\))) ?)?(((\d{2}[\ \-\.]?){3,5}\d{2})|((\d{3}[\ \-\.]?){2}\d{4}))$

通过接受的答案中提供的良好解释,对此的理解应该相对容易。

这是一个 live demo