Here's another non-regex way to do it:
def validate_email(email):
user, sep, domain = email.partition('@')
parts = [user]
parts.extend(domain.split('.'))
return len(parts) == 3 and all(part.isalnum() for part in parts)
>>> for email in 'a@b.c', 'ab23@f45.d3', 'a_b@p_q.com', '@bc.d', '123.c@cvb', '', '@', 'a@b@c', '@.', 'abc&**&@test.com':
... print(validate_email(email))
True
True
False
False
False
False
False
False
False
False
The domain part of the email address is restricted to two parts separated by a .
. Valid email domains can have at least three parts so, if you want to support that, remove the len(parts) == 3
test.
And here is a regex pattern that works:
import re
def validate_email(email):
return re.match(r'[a-zA-Z\d]+@[a-zA-Z\d]+\.[a-zA-Z\d]+$', email) != None
>>> for email in 'a@b.c', 'ab23@f45.d3', 'a_b@p_q.com', '@bc.d', '123.c@cvb', '', '@', 'a@b@c', '@.', 'abc&**&@test.com':
... print(validate_email(email))
True
True
False
False
False
False
False
False
False
False
You can't use \w
in the pattern because this will match the underscore character and this is not normally considered alphanumeric. The $
is required at the end of the pattern to ensure that the last segment of the email address ends with alphanumeric characters only. With out this extraneous invalid characters appearing at the end of the string after a sequence of valid characters will match.
In this case I'd opt for the first method using just basic string functions because it is (arguably) easier to read and maintain than a regex.