← Go Back

How to Validate an Email Address

The following function checks whether a string represents a well-formed email address. It is typically useful in registration forms to validate information entered by the user.

The code was taken and briefly modified from the web2py source code (gluon/validators.py), which at the same time was based on the solution proposed in this article. The rules that constitute a valid email address are defined using regular expressions with the re standard module.

import re

body_regex = re.compile('''
^(?!\.) # name may not begin with a dot
[-a-z0-9!\#$%&'*+/=?^_`{|}~] # all legal characters except dot
(?<!\.)\. # single dots only
(?<!\.)$ # name may not end with a dot
domain_regex = re.compile('''
# [sub]domain begins with alphanumeric
[-\w]* # alphanumeric, underscore, dot, hyphen
[a-z0-9] # ending alphanumeric
\. # ending dot
[a-z]{2,} # TLD alpha-only

def is_valid_email(email):
if not isinstance(email, str) or not email or '@' not in email:
return False

body, domain = email.rsplit('@', 1)

match_body = body_regex.match(body)
match_domain = domain_regex.match(domain)

if not match_domain:
# check for Internationalized Domain Names
# see https://docs.python.org/2/library/codecs.html#module-encodings.idna
domain_encoded = domain.encode('idna').decode('ascii')
except UnicodeError:
return False
match_domain = domain_regex.match(domain_encoded)

return (match_body is not None) and (match_domain is not None)


print(is_valid_email('a@b.com'))  # True.
print(is_valid_email('abc@def.com')) # True.
print(is_valid_email('abc@3def.com')) # True.
print(is_valid_email('abc@def.us')) # True.
print(is_valid_email('abc@d_-f.us')) # True.
print(is_valid_email('@def.com')) # False.
print(is_valid_email('"abc@def".com')) # False.
print(is_valid_email('abc+def.com')) # False.
print(is_valid_email('abc@def.x')) # False.
print(is_valid_email('abc@def.12')) # False.
print(is_valid_email('abc@def..com')) # False.

re email