Expressão regular para corresponder ao número de telefone padrão de 10 dígitos

Quero escrever uma expressão regular para um número de telefone padrão dos EUA que suporte os seguintes formatos:

###-###-#### (###) ###-#### ### ### #### ###.###.#### 

onde # significa qualquer número. Até agora eu vim com as seguintes expressões

 ^[1-9]\d{2}-\d{3}-\d{4} ^\(\d{3}\)\s\d{3}-\d{4} ^[1-9]\d{2}\s\d{3}\s\d{4} ^[1-9]\d{2}\.\d{3}\.\d{4} 

respectivamente. Não tenho certeza se o último está correto para o cheque pontilhado. Eu também quero saber se existe alguma maneira de escrever uma única expressão em vez das 4 diferentes que atendem aos diferentes formatos que mencionei. Se assim for, não tenho a certeza como faço isso. E também como modifico a expressão / expressões para que eu também possa include uma condição para suportar o código de área como componente opcional. Algo como

 +1 ### ### #### 

onde +1 é o código de área e é opcional.

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

    Corresponde ao seguinte

     123-456-7890 (123) 456-7890 123 456 7890 123.456.7890 +91 (123) 456-7890 

    Se você não quiser uma correspondência em números fora dos EUA, use

     ^(\+0?1\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$ 

    Atualização:
    Como notado pelo usuário Simon Weaver abaixo, se você também estiver interessado em corresponder em números não formatados, apenas torne a class de caractere separador opcional como [\s.-]?

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

    Existem muitas variações possíveis para este problema. Aqui está uma expressão regular semelhante a uma resposta que eu coloquei anteriormente no SO.

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

    Isso corresponderia aos exemplos a seguir e muito mais:

     18005551234 1 800 555 1234 +1 800 555-1234 +86 800 555 1234 1-800-555-1234 1 (800) 555-1234 (800)555-1234 (800) 555-1234 (800)5551234 800-555-1234 800.555.1234 800 555 1234x5678 8005551234 x5678 1 800 555-1234 1----800----555-1234 

    Independentemente da maneira como o número de telefone é inserido, os grupos de captura podem ser usados ​​para dividir o número de telefone para que você possa processá-lo em seu código.

    • Grupo1: Código do país (ex: 1 ou 86)
    • Grupo2: Código de Área (ex: 800)
    • Grupo3: Troca (ex: 555)
    • Grupo4: Número do Assinante (ex: 1234)
    • Grupo 5: Extensão (ex: 5678)

    Aqui está um detalhamento da expressão, se você estiver interessado:

     ^\s* #Line start, match any whitespaces at the beginning if any. (?:\+?(\d{1,3}))? #GROUP 1: The country code. Optional. [-. (]* #Allow certain non numeric characters that may appear between the Country Code and the Area Code. (\d{3}) #GROUP 2: The Area Code. Required. [-. )]* #Allow certain non numeric characters that may appear between the Area Code and the Exchange number. (\d{3}) #GROUP 3: The Exchange number. Required. [-. ]* #Allow certain non numeric characters that may appear between the Exchange number and the Subscriber number. (\d{4}) #Group 4: The Subscriber Number. Required. (?: *x(\d+))? #Group 5: The Extension number. Optional. \s*$ #Match any ending whitespaces if any and the end of string. 

    Para tornar o Código de Área opcional, basta adicionar um ponto de interrogação após o (\ d {3}) para o código de área.

    Adicionando um exemplo usando as soluções acima mencionadas no jsfiddle. Eu modifiquei o código um pouco como por minha exigência de clientes. Espero que isso também ajude alguém.

     /^\s*(?:\+?(\d{1,3}))?[- (]*(\d{3})[- )]*(\d{3})[- ]*(\d{4})(?: *[x/#]{1}(\d+))?\s*$/ 

    Veja o exemplo aqui

    Aqui está um bastante compacto que eu criei.

     Search: \+?1?\s*\(?-*\.*(\d{3})\)?\.*-*\s*(\d{3})\.*-*\s*(\d{4})$ Replace: +1 \($1\) $2-$3 

    Testado contra os seguintes casos de uso.

     18001234567 1 800 123 4567 1-800-123-4567 +18001234567 +1 800 123 4567 +1 (800) 123 4567 1(800)1234567 +1800 1234567 1.8001234567 1.800.123.4567 1--800--123--4567 +1 (800) 123-4567 

    As expressões para 1, 3 e 4 são bem parecidas, então você pode usar:

     ^([1-9]\d{2})([- .])(\d{3})$2(\d{4})$ 

    Observe que, dependendo do idioma e da marca dos regexes usados, talvez seja necessário colocar \2 vez de $2 ou essa correspondência pode não ser suportada.

    Não vejo uma boa maneira de combinar isso com o formato 2, além do óbvio ^(regex for 1,3,4|regex for 2)$ que é feio, desajeitado e dificulta a saída das partes dos números.

    Quanto ao código de área, você pode adicionar (\+\d)? para o início para capturar um código de área de um dígito (desculpe, eu não sei o formato dos seus códigos de área).

    Que tal agora?

     ^(\+?[01])?[-.\s]?\(?[1-9]\d{2}\)?[-.\s]?\d{3}[-.\s]?\d{4} 

    EDIT: eu esqueci sobre o () um. EDIT 2: Tem a primeira parte de 3 dígitos errada.

    tente isso para os usuários paquistaneses. Aqui está um bastante compacto que eu criei.

     ((\+92)|0)[.\- ]?[0-9][.\- ]?[0-9][.\- ]?[0-9] 

    Testado contra os seguintes casos de uso.

     +92 -345 -123 -4567 +92 333 123 4567 +92 300 123 4567 +92 321 123 -4567 +92 345 - 540 - 5883 

    Esse código corresponderá a um número de telefone dos EUA ou do Canadá e também garantirá que ele seja um código de área e uma troca válidos:

     ^((\+1)?[\s-]?)?\(?[2-9]\d\d\)?[\s-]?[2-9]\d\d[\s-]?\d\d\d\d 

    Teste no Regex101.com

    Regex patter para validar um número de telefone normal de 10 dígitos mais o código internacional opcional (1 a 3 dígitos) e o número de extensão opcional (qualquer número de dígitos):

     /(\+\d{1,3}\s?)?((\(\d{3}\)\s?)|(\d{3})(\s|-?))(\d{3}(\s|-?))(\d{4})(\s?(([E|e]xt[:|.|]?)|x|X)(\s?\d+))?/g 

    Demonstração: https://www.regextester.com/103299

    Entradas válidas:

     /* Full number */ +999 (999) 999-9999 Ext. 99999 /* Regular local phone number (XXX) XXX-XXXX */ 1231231231 123-1231231 123123-1231 123-123 1231 123 123-1231 123-123-1231 (123)123-1231 (123)123 1231 (123) 123-1231 (123) 123 1231 /* International codes +XXX (XXX) XXX-XXXX */ +99 1234567890 +991234567890 /* Extensions (XXX) XXX-XXXX Ext. XXX... */ 1234567890 Ext 1123123 1234567890Ext 1123123 1234567890 Ext1123123 1234567890Ext1123123 1234567890 Ext: 1123123 1234567890Ext: 1123123 1234567890 Ext:1123123 1234567890Ext:1123123 1234567890 Ext. 1123123 1234567890Ext. 1123123 1234567890 Ext.1123123 1234567890Ext.1123123 1234567890 ext 1123123 1234567890ext 1123123 1234567890 ext1123123 1234567890ext1123123 1234567890 ext: 1123123 1234567890ext: 1123123 1234567890 ext:1123123 1234567890ext:1123123 1234567890 X 1123123 1234567890X1123123 1234567890X 1123123 1234567890 X1123123 1234567890 x 1123123 1234567890x1123123 1234567890 x1123123 1234567890x 1123123 
     ^(\+1)?\s?(\([1-9]\d{2}\)|[1-9]\d{2})(-|\s|.)\d{3}(-|\s|.)\d{4} 

    Começando com a resposta do @Ravi, eu também apliquei algumas regras de validação para o código NPA (Área) .

    Em particular:

    • Deve começar com um 2 (ou superior)
    • Não pode ter “11” como segundo e terceiro dígitos (N11).

    Existem algumas outras restrições, incluindo blocos reservados (N9X, 37X, 96X) e 555, mas eu os deixei de fora, particularmente porque os blocos reservados podem ver uso futuro, e 555 é útil para testes.

    Isto é o que eu criei:

     ^((\+\d{1,2}|1)[\s.-]?)?\(?[2-9](?!11)\d{2}\)?[\s.-]?\d{3}[\s.-]?\d{4}$ 

    Como alternativa, se você também quiser corresponder valores em branco (se o campo não for obrigatório), você poderá usar:

     (^((\+\d{1,2}|1)[\s.-]?)?\(?[2-9](?!11)\d{2}\)?[\s.-]?\d{3}[\s.-]?\d{4}$|^$) 

    Meus casos de teste para números válidos (muitos da resposta de @Francis) são:

     18005551234 1 800 555 1234 +1 800 555-1234 +86 800 555 1234 1-800-555-1234 1.800.555.1234 +1.800.555.1234 1 (800) 555-1234 (800)555-1234 (800) 555-1234 (800)5551234 800-555-1234 800.555.1234 

    Meus casos de teste inválidos incluem:

     (003) 555-1212 // Area code starts with 0 (103) 555-1212 // Area code starts with 1 (911) 555-1212 // Area code ends with 11 180055512345 // Too many digits 1 800 5555 1234 // Prefix code too long +1 800 555x1234 // Invalid delimiter +867 800 555 1234 // Country code too long 1-800-555-1234p // Invalid character 1 (800) 555-1234 // Too many spaces 800x555x1234 // Invalid delimiter 86 800 555 1212 // Non-NA country code doesn't have + 

    Minha expressão regular não inclui o agrupamento para extrair os grupos de dígitos, mas pode ser modificado para incluí-los.

    Esta é uma versão mais abrangente que vai corresponder tanto quanto eu posso pensar, bem como dar-lhe a correspondência do grupo para o país, região, primeiro e último.

     (?(\+?(?(\d{1,3}))(\s|-|\.)?)?(\(?(?(\d{3}))\)?(\s|-|\.)?)((?(\d{3}))(\s|-|\.)?)((?(\d{4})))) 

    Talvez o mais fácil se compare a vários outros.

     \(?\d+\)?[-.\s]?\d+[-.\s]?\d+ 

    Ele corresponde ao seguinte:

    (555) 444-6789

    555-444-6789

    555.444.6789

    555 444 6789

    Que tal vários números com “+” e separá-los com “;” “,” “-” ou “” caracteres?

    Acabei com

    const regexBase = '(?:\\+?(\\d{1,3}))?[-. (]*(\\d{3})?[-. )]*(\\d{3})[-. ]*(\\d{4,5})(?: *x(\\d+))?'; const phoneRegex = new RegExp('\\s*' + regexBase + '\\s*', 'g');

    isso era para permitir coisas como números holandeses, por exemplo

    +358 300 20200