Olá pessoal, sobre este tema, procurei bastante e não encontrei nenhuma resposta clara, então, segui a dica dos instrutores e fui fuçar na documentação do Re, caso tenha curiosidade também, é possível acessar aqui. Bom, depois de testar algumas vezes creio ter conseguido uma resposta que, na minha situação, resolve.
Funciona com o seguinte padrão:
([0-9]{2,3}?)?([1-9]{2})([6-9])?([0-9]{4})([0-9]{4}$)
Este padrão se divide em 5 grupos, sendo:
- ([0-9]{2,3}?)? --> esta parte analisa os primeiros dígitos de uma forma que a documentação chama de non-greedy, basicamente ele tenta preencher o grupo com o menor numero possível de combinações, neste caso {2,3}?, ele força o 2, caso "sobre" um digito, completa com 3.
- ([1-9]{2}) --> Verificação simples de DDD
- ([6-9])? --> Verificação do 9º dígito, a '?' faz com que este campo não seja obrigatório, coloquei de [6-9] pois por padrão, celulares começam com estes dígitos, apesar de no Brasil estarmos utilizando apenas o dígito "9".
- ([0-9]{4}) --> Diz que o 4º grupo obrigatoriamente tem que ter 4 dígitos.
- ([0-9]{4})$ --> Por fim, temos esta expressão terminada em '$' que 'força' caber na expressão inteira, este sinal se faz necessário por causa da expressão do primeiro passo, se você não colocar seu padrão poderá ignorar o último dígito de um telefone, já que ele vai forçar o grupo 1 a ter 2 dígitos
Então é como se lêssemos de trás para frente, os últimos 4 dígitos estão forçados, ai temos mais 4 dígitos, então, verifica se existe um 9º dígito, estão, encaixa os 2 dígitos de DDD e por fim de 0, 2 ou 3 dígitos de DDI desde que seja a menor combinação possível.
Claro, sei que isso não resolve tudo, como por exemplo, e se meu cliente enviar 1 dígito a mais? Bom, pensando nisso, eu testei algo que creio não ser o método mais pythonico que existe, mas estou só começando, então, resolve... Para validar a quantidade de dígitos eu utilizei um if, da seguinte forma:
import re
texto = "155 45 988764 1343 "
numero = texto.replace(' ', '') #Usei esta parte apenas para poder copiar diversos números da internet e não precisar ficar formatando manualmente, osb.: não sei porque o método strip() não rolou.
print(numero) # Printa 15545987641343
padrao = "([0-9]{2,3}?)?([1-9]{2})([6-9])?([0-9]{4})([0-9]{4}$)"
if len(numero) in range(6, 15):
telefone = re.search(padrao, numero)
E para verificar os valores podemos usar:
print(telefone.group(1)) # Printa 155
print(telefone.group(2)) # Printa 45
print(telefone.group(3)) # Printa 9, quando número não tem 9º dígito aqui retorna None
print(telefone.group(4)) # Printa 8764
print(telefone.group(5)) # Printa 1343
É importante ter em mente que o grupo 3 pode voltar None em caso de números celular sem 9º dígito, só reforçando...
Então, para uso na aula precisamos de mais 1 if para verificar se o grupo 3 é None:
cod = telefone.group # Só para facilitar a vida e diminuir o tamanho a fstring
if telefone.group(3) is None:
print(f"+{cod(1)} ({cod(2)}) {cod(4)}-{cod(5)}")
else:
print(f"+{cod(1)} ({cod(2)}) {cod(3)}{cod(4)}-{cod(5)}")
Bom, assim eu resolvi esta situação, espero ter ajudado e que me ajudem a validar mais números, testei vários DDIs, mas o mundo é grande pakas e é osso saber se vai dar match sempre.
Como foi meu primeiro post, espero ter formatado minimamente bem. Vlws, flws povo.