TransWikia.com

Como fazer uma expressão regular para telefone celular?

Stack Overflow em Português Asked by WellDotCom on November 13, 2021

Como criar uma expressão regular para validar o campo telefone que aceite
99-99999999 (DDD + 8 números) ou 99-999999999 (DDD + 9 números). E que ao digitar ele adicione o traço automaticamente!

ValidationExpression="^[0-9]{2}-([0-9]{8}|[0-9]{9})"

Como proceder?

5 Answers

^([1-9]{2}) 9[7-9]{1}[0-9]{3}-[0-9]{4}$
  • [1-9]{2} = Dois dígitos de 1 a 9. Não existem DDD com o dígito 0.
  • 9 = Todos os celulares a partir de 2016 começam por 9
  • [7-9]{1} = Na numeração antiga os celulares começavam com 7, 8 ou 9
  • [0-9]{3} = Os três outros dígitos podem ser de 0 à 9
  • [0-9]{4} = Os quatro depois do hífen podem ser de 0 à 9

Answered by Eduardo de Souza on November 13, 2021

Minha solução pode não ser a mais efetiva, mas como não vi muitas soluções comentando sobre alguns pontos resolvi escrever a minha.

Eu criei uma expressão regular que identifica se uma string é um telefone, levando em conta os seguintes casos:

  • Telefones 0800
  • Números de operadoras e serviços como 10315 e 190
  • Telefones representados com ou sem parênteses
  • Aceita operadora representada como 0xx11
  • Telefones com ou sem os separadores [ .-]
  • Ignora telefones começados com 0 se não tiver DDD (ex: 0999-9999 não é aceito, mas 0xx11 9123-1234 é)

Ficou um pouco grande e difícil de ler humanamente, mas atende meus projetos:

/^1dd(dd)?$|^0800 ?d{3} ?d{4}$|^((0?([1-9a-zA-Z][0-9a-zA-Z])?[1-9]d) ?|0?([1-9a-zA-Z][0-9a-zA-Z])?[1-9]d[ .-]?)?(9|9[ .-])?[2-9]d{3}[ .-]?d{4}$/gm

Você pode ver a expressão em uso neste link.

Depois de validar se a expressão é um telefone, você pode formatar do jeito que achar melhor manipulando a string.

Segue um exemplo em Java (onde PHONE_MATCH é a expressão regular):

public String phone(String phoneString) throws IllegalArgumentException {
    if (!phoneString.matches(PHONE_MATCH)) {
        throw new IllegalArgumentException("Not a valid phone format");
    }

    String str = phoneString.replaceAll("[^\d]", "");

    if (str.charAt(0) == '0') {
        if (str.charAt(1) == '0') {
            str = str.substring(2);
        } else {
            str = str.substring(1);
        }
    }

    switch (str.length()) {
        case 8:
            return applyMask(str, "AAAA-AAAA", 'A');
        case 9:
            return applyMask(str, "AAAAA-AAAA", 'A');
        case 10:
            return applyMask(str, "(AA) AAAA-AAAA", 'A');
        case 11:
            return applyMask(str, "(AA) AAAAA-AAAA", 'A');
        default:
            return str;
    }
}

Método applyMask:

public String applyMask(String str, String mask, char specialChar) {

    // Conta quantos caracteres especiais existem na máscara
    int maskChCount = mask.length() - mask.replaceAll("[^" + specialChar + "]", "").length();

    // Conta apenas os números
    int strChCount = str.length() - str.replaceAll("\d", "").length();

    // Exceção caso a string nao tenha números suficientes para competar a máscara
    if (strChCount < maskChCount) {
        throw new IllegalArgumentException("The number of chars in the string should not be smaller than the " +
                "number of special chars in the mask");
    }

    char[] maskChars = mask.toCharArray();
    char[] strChars = str.toCharArray();

    // Itera por todos os elementos da máscara
    for (int i = 0, j = 0; i < maskChars.length && j < strChars.length; i++) {
        char ch = maskChars[i];
        char sh = strChars[j];

        if (ch == specialChar) {
            // Se achou o caractere especial, buscar o próximo elemento aceito da String e 
            // substituí-lo no local do caractere especial
            while (!Character.toString(sh).matches("\d")) {
                j++;
                sh = strChars[j];
            }
            maskChars[i] = sh;
            j++;
        }
    }

    return new String(maskChars);
}

Acredito que tenha várias formas de otimizar este código, qualquer sugestão é bem vinda.

Answered by Felipe Andrade on November 13, 2021

Gente, com a ajuda de vocês eu criei uma string que achei ideal para mim. Simples e direta. No WHMCS use para iniciar e fechar /. Não usarei no exemplo para seguir o exemplo de vocês. Vamos lá. A expressão fica assim:

^([1-9]{2}) [9]{0,1}[6-9]{1}[0-9]{3}-[0-9]{4}$

Explicação:

  • ^ = Início da string.
  • ( = Um abre parênteses.
  • [1-9]{2} = Dois dígitos de 1 a 9. Não existem códigos de DDD com o dígito 0.
  • ) = Um fecha parênteses.
  • = Um espaço em branco.
  • [9]{0,1} = O primeiro dígito é 9, mais ele pode ou não existir daí o "0" ou "1" dentro da {0,1}.
  • [6-9]{1} = o segundo dígito pode ser de 6 à 9.
  • [0-9]{3} = Os três outros dígitos são de 0 à 9
  • - = Um hífen.
  • [0-9]{4} = A segunda metade do número do telefone.
  • $ = Final da string.

Lembrando amigos que no WHMCS se deve iniciar e fechar com /. Até o final de 2016 ou mais preciso em 06 de novembro de 2016 todo o Brasil terá o 9 no início dos celulares.

Answered by Fábio Seabra on November 13, 2021

Eu uso essa

@"^(?d{2})?[s-]?[s9]?d{4}-?d{4}$"

se você coloca 9 dígitos ela te obrigado que o primeiro digito seja 9.

Eu pegaria um pouco de cada exemplo pra montar a ideal.

Answered by Gabriel Santos Reis on November 13, 2021

Hoje em dia todos os telefones celulares no Brasil têm nove dígitos e iniciam com o dígito 9 e todos os telefones fixos têm 8 dígitos e nunca iniciam com o dígito 9. Eu pessoalmente preferiria formatar o telefone como (xx) xxxxx-xxxx. Assim sendo, a melhor expressão regular para isso seria essa:

^([1-9]{2}) (?:[2-8]|9[1-9])[0-9]{3}-[0-9]{4}$

A explicação completa dela é:

  • ^ - Início da string.
  • ( - Um abre parênteses.
  • [1-9]{2} - Dois dígitos de 1 a 9. Não existem códigos de DDD com o dígito 0.
  • ) - Um fecha parênteses.
  • - Um espaço em branco.
  • (?:[2-8]|9[1-9]) - O início do número. Representa uma escolha entre o um dígito entre 2 e 8 (a parte do [2-8]) e de um 9 seguido de um dígito de 1 a 9 (a parte do 9[1-9]). O | separa as opções a serem escolhidas. O (?: ... ) agrupa tais escolhas. Telefones fixos começam com dígitos de 2 a 8. Telefones celulares começam com 9 e têm um segundo dígito de 1 a 9. O primeiro dígito nunca será 0 ou 1. Celulares não podem começar com 90 porque esse é o prefixo para ligações a cobrar.
  • [0-9]{3} - Os demais três dígitos da primeira metade do número do telefone, perfazendo um total de 4 ou 5 dígitos na primeira metade.
  • - - Um hífen.
  • [0-9]{4} - A segunda metade do número do telefone.
  • $ - Final da string.

Se você quiser deixar os parênteses, o espaço em branco e hífen opcionais, então você pode colocar um ? após cada um desses símbolos, resultando nesta expressão regular:

^(?[1-9]{2})? ?(?:[2-8]|9[1-9])[0-9]{3}-?[0-9]{4}$

Se você quiser, também é possível também filtrar os DDDs que existem. Eis uma imagem que mostra os códigos de área existentes no momento de acordo com a Wikipédia:

Mapa do Brasil com as divisões por DDD

Olhando-se então para esse mapa, a subexpressão que filtraria os DDDs válidos seria a seguinte:

(?:[14689][1-9]|2[12478]|3[1234578]|5[1345]|7[134579])

Como já explicado, o (?: ... ) é para agrupar. As opções (separadas por |) seriam grupos de dois dígitos, que seria uma das seguintes opções: 2[12478] para Rio de Janeiro e Espírito Santo, 3[1234578] para Minas Gerais, 5[1345] para Rio Grande do Sul, 7[134579] para Bahia e Sergipe e [14689][1-9] para o restante do Brasil.

E a expressão regular completa seria a seguinte (com os parênteses, espaços e hífens obrigatórios):

^((?:[14689][1-9]|2[12478]|3[1234578]|5[1345]|7[134579])) (?:[2-8]|9[1-9])[0-9]{3}-[0-9]{4}$

E com eles não obrigatórios:

^(?(?:[14689][1-9]|2[12478]|3[1234578]|5[1345]|7[134579]))? ?(?:[2-8]|9[1-9])[0-9]{3}-?[0-9]{4}$

NOTA: Esta resposta foi escrita originalmente em 2015, quando haviam celulares de 8 ou 9 dígitos, dependendo do DDD. Desde então, ela foi atualizada para o formato mais novo em vigor, que sempre têm 9 dígitos. Se quiser mais detalhes sobre como esta resposta foi editada, confira o histórico de edições.

Answered by Victor Stafusa on November 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP