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?
^([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 à 9Answered 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:
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
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP