简体   繁体   中英

Telephone number regex all formats

I'm developing an expression to validate all possible phone number formats. I have 50%, it is not validating me the admitted characters by means of * . - whitespace * . - whitespace

These are the rules

It can contain open and close parenthesis ex. (55)

It can contin or not '+' char ex. (+52)

It can contain 2 or 3 numbers inside parenthesis ex. (+555) o (+55)

It can contain whitespace between close parenthesis and the next numbers ex. (55) 44332211

The consecutive numbers to the parenthesis must be 6 or 8 numbers ex. (55)443322 o (55)44332211

The consecutive numbers to the parenthesis can contain whitespaces, dashes, asterisks, or colons. ex.(55)44-33-22-11 o (55)44 33 22 11 o (55)44*33*22*11 o (55)44.33.22.11

The consecutive numbers to the parenthesis can be divided in groups of 2, 3 or 4 numbers ex. (55)5544-3322 o (55)55 44 33 22 o (555)444*333

The number format can come in a row of 8, 10 o 12 numbers ex. 55443322 o 5544332211 o 554433221100

This is the regular expression

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

This is a map of the regular expression在此处输入图片说明

What am I doing wrong? I leave an example script, the regex I'm doing for Python, I do not know if I change a lot with 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>

You may use

^(?:\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})?))$

See the regex demo .

Details

  • ^ - start of string
  • (?: - start of an outer grouping construct:
    • \\d{8} - 8 digits
    • (?:\\d{2}(?:\\d{2})?)? - optional 2 digits that are followed with an optional 2 digit substring (so, 8, 10 or 12 digit string can be matched)
  • | - or

    • \\( - a (
    • \\+? - 1 or 0 pluses
    • \\d{2,3} - 2 or 3 digits
    • \\) - a ) char
    • \\s? - 1 or 0 whitespaces
    • (?: - a grouping:
      • \\d{4} - 4 digits
      • [\\s*.-]? - a whitespace, * , . or - , an optional occurrence
      • \\d{4} - 4 digits
    • | - or
      • \\d{3}[\\s*.-]?\\d{3} - 3 digits, a delimiter char, 3 digits
    • | - or

      • \\d{2}([\\s*.-]?)\\d{2}\\1\\d{2}(?:\\1\\d{2})? : 2 digits, a separator char captured into Group 1, 2 digits, the same separator as in Group 1, 2 digits, and an optional sequence of the same separator char as in Group 1 and two digits
    • ) - end of the inner grouping.

  • ) - end of the outer grouping
  • $ - end of string.

Another possible solution (one which might be a lot easier) is to simply validate the phone number at the source, then only allow this one format on the server side.

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

The above snippet may look scary long, but rest assured that it goes down to a measly 1008 bytes after minification (only 486 bytes after zopfli gzip is applied).

 !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"/>

Accepted answer has a lot of flaws:

  • \\s is not only for whitespace characters but also for \\r and \\n.

     +11 1111 1111 #This matches
  • Minimum digits of a number is 8 and maximum is 12 but these digits have nothing to do with the international prefix digits:

     (+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
  • The international prefix matches only between brackets

    +39 3475 4087 18 # this is valid but doesn't match
  • Regex is not trivial, long, complex and bugged for no reason.

I made this one to overcome those flaws and improve it:

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

The understanding of this should be relatively easy with the good explanation provided in the accepted answer.

This is a live demo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM