re.search also validates invalid emails

Asked

Viewed 32 times

0

I’m having some problems with this email validation. Any text I put in it validates and accepts. What causes this?

import re

def email_validation(email):
        regex = "^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)$"
        try:
            if re.search(regex,email):
                return email        
        except:
            raise Exception("Email inválido")

1 answer

0


See in the documentation that search returns None if nothing is found, but at no time does he cast exception, then he will not fall into the except. So just see if the return is None, something like that:

def email_validation(email):
    regex = r"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)$"
    if re.search(regex, email) is None:
        raise Exception('Email inválido')
    return email        

Note also that I used one raw literal string (with the "r" before quotation marks) so that the \ is correctly interpreted within the expression.


But I don’t really know what to return the email itself for if it is valid (and I wonder if making an exception would be the best way to validate), so another suggestion is to make the function return only if the email is valid or not (just True or False):

# retorna True se o email é válido, False se for inválido
def email_validation(email):
    regex = r"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)$"
    return re.search(regex, email) is not None

And then whoever calls the job decides what to do with the result:

if email_validation('[email protected]'):
    print('email válido')
else:
    print('email inválido')

Then you can choose whether to show a message, throw an exception, etc. The function only has the responsibility to tell if the email is valid or not, what happens next is up to whom to call it. I see no need to launch an exception if you can solve with a return boolean.


Another detail is that the documentation says that if an expression is used multiple times (as it seems it will be the case), it may be interesting to compile it before.

So an alternative is to use re.compile to leave regex already compiled:

def email_validation(email, regex=re.compile(r"^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)$")):
    return regex.search(email) is not None

Thus the regex is compiled only once, and you can call the function several times without having to recreate it. And by setting it as a parameter, you can change the regex if you want:

# valida usando a regex default
email_validation(email)

# valida usando outra regex
email_validation(email, re.compile('outra regex...'))

Finally, I didn’t get to analyze regex. But about using regex to validate emails, there are a few things here, here, here and here (this last link has some options at the end, just do not recommend the last regex).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.