Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check for valid email address? [duplicate]

Is there a good way to check a form input using regex to make sure it is a proper style email address? Been searching since last night and everybody that has answered peoples questions regarding this topic also seems to have problems with it if it is a subdomained email address.

like image 615
Bobby Avatar asked Nov 05 '11 19:11

Bobby


People also ask

How do you check if an email address is already taken?

Just visit www.email-checker.net to use this tool. Enter the email address you would like to check and Email Checker will show you the results.

Can an email address be duplicated?

Duplicates of the same message will occur if your email account is configured to forward email to multiple addresses. For example, the original may arrive in your business acount with a copy forwarded to your home account. They will both arrive in the same inbox if the same mail client is checking both addresses.

What are two ways to validate an email address?

There are many free tools that also validate email addresses; ValidateEmailAddress, EmailValidator and Pabbly Email Verification are few of such examples. First, you need to bulk upload your list of email IDs.

How can I check if an email address is valid for free?

The best and most recommended ways to verify an email address without sending an email are: Email verifier tools: Use an email verification service to check if the given address is valid or not. Just google 'Email Verifier,' and many free and paid options will come up.


12 Answers

There is no point. Even if you can verify that the email address is syntactically valid, you'll still need to check that it was not mistyped, and that it actually goes to the person you think it does. The only way to do that is to send them an email and have them click a link to verify.

Therefore, a most basic check (e.g. that they didn't accidentally entered their street address) is usually enough. Something like: it has exactly one @ sign, and at least one . in the part after the @:

[^@]+@[^@]+\.[^@]+

You'd probably also want to disallow whitespace -- there are probably valid email addresses with whitespace in them, but I've never seen one, so the odds of this being a user error are on your side.

If you want the full check, have a look at this question.


Update: Here's how you could use any such regex:

import re

if not re.match(r"... regex here ...", email):
  # whatever

Python ≥3.4 has re.fullmatch which is preferable to re.match.

Note the r in front of the string; this way, you won't need to escape things twice.

If you have a large number of regexes to check, it might be faster to compile the regex first:

import re

EMAIL_REGEX = re.compile(r"... regex here ...")

if not EMAIL_REGEX.match(email):
  # whatever

Another option is to use the validate_email package, which actually contacts the SMTP server to verify that the address exists. This still doesn't guarantee that it belongs to the right person, though.

like image 99
Thomas Avatar answered Oct 06 '22 01:10

Thomas


The Python standard library comes with an e-mail parsing function: email.utils.parseaddr().

It returns a two-tuple containing the real name and the actual address parts of the e-mail:

>>> from email.utils import parseaddr
>>> parseaddr('[email protected]')
('', '[email protected]')

>>> parseaddr('Full Name <[email protected]>')
('Full Name', '[email protected]')

>>> parseaddr('"Full Name with quotes and <[email protected]>" <[email protected]>')
('Full Name with quotes and <[email protected]>', '[email protected]')

And if the parsing is unsuccessful, it returns a two-tuple of empty strings:

>>> parseaddr('[invalid!email]')
('', '')

An issue with this parser is that it's accepting of anything that is considered as a valid e-mail address for RFC-822 and friends, including many things that are clearly not addressable on the wide Internet:

>>> parseaddr('invalid@example,com') # notice the comma
('', 'invalid@example')

>>> parseaddr('invalid-email')
('', 'invalid-email')

So, as @TokenMacGuy put it, the only definitive way of checking an e-mail address is to send an e-mail to the expected address and wait for the user to act on the information inside the message.

However, you might want to check for, at least, the presence of an @-sign on the second tuple element, as @bvukelic suggests:

>>> '@' in parseaddr("invalid-email")[1]
False

If you want to go a step further, you can install the dnspython project and resolve the mail servers for the e-mail domain (the part after the '@'), only trying to send an e-mail if there are actual MX servers:

>>> from dns.resolver import query
>>> domain = 'foo@[email protected]'.rsplit('@', 1)[-1]
>>> bool(query(domain, 'MX'))
True
>>> query('example.com', 'MX')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  [...]
dns.resolver.NoAnswer
>>> query('not-a-domain', 'MX')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  [...]
dns.resolver.NXDOMAIN

You can catch both NoAnswer and NXDOMAIN by catching dns.exception.DNSException.

And Yes, foo@[email protected] is a syntactically valid address. Only the last @ should be considered for detecting where the domain part starts.

like image 40
LeoRochael Avatar answered Oct 06 '22 01:10

LeoRochael


I haven't seen the answer already here among the mess of custom Regex answers, but...

There exists a python library called py3-validate-email validate_email which has 3 levels of email validation, including asking a valid SMTP server if the email address is valid (without sending an email).

To install

python -m pip install py3-validate-email

Basic usage:

from validate_email import validate_email
is_valid = validate_email(email_address='[email protected]', \
    check_regex=True, check_mx=True, \
    from_address='[email protected]', helo_host='my.host.name', \ 
    smtp_timeout=10, dns_timeout=10, use_blacklist=True)

For those interested in the dirty details, validate_email.py (source) aims to be faithful to RFC 2822.

All we are really doing is comparing the input string to one gigantic regular expression. But building that regexp, and ensuring its correctness, is made much easier by assembling it from the "tokens" defined by the RFC. Each of these tokens is tested in the accompanying unit test file.


you may need the pyDNS module for checking SMTP servers

pip install pyDNS

or from Ubuntu

apt-get install python3-dns
like image 45
philshem Avatar answered Oct 05 '22 23:10

philshem


Email addresses are not as simple as they seem! For example, Bob_O'[email protected], is a valid email address.

I've had some luck with the lepl package (http://www.acooke.org/lepl/). It can validate email addresses as indicated in RFC 3696: http://www.faqs.org/rfcs/rfc3696.html

Found some old code:

import lepl.apps.rfc3696
email_validator = lepl.apps.rfc3696.Email()
if not email_validator("[email protected]"):
    print "Invalid email"
like image 20
bigendian Avatar answered Oct 06 '22 00:10

bigendian


I found an excellent (and tested) way to check for valid email address. I paste my code here:

# here i import the module that implements regular expressions
import re

# here is my function to check for valid email address
def test_email(your_pattern):
  pattern = re.compile(your_pattern)
  # here is an example list of email to check it at the end
  emails = ["[email protected]", "[email protected]", "wha.t.`1an?ug{}[email protected]"]
  for email in emails:
    if not re.match(pattern, email):
        print "You failed to match %s" % (email)
    elif not your_pattern:
        print "Forgot to enter a pattern!"
    else:
        print "Pass"

# my pattern that is passed as argument in my function is here!
pattern = r"\"?([-a-zA-Z0-9.`?{}]+@\w+\.\w+)\"?"   

# here i test my function passing my pattern
test_email(pattern)
like image 40
James The Beard Avatar answered Oct 05 '22 23:10

James The Beard


I see a lot of complicated answers here. Some of them, fail to knowledge simple, true email address, or have false positives. Below, is the simplest way of testing that the string would be a valid email. It tests against 2 and 3 letter TLD's. Now that you technically can have larger ones, you may wish to increase the 3 to 4, 5 or even 10.

import re
def valid_email(email):
  return bool(re.search(r"^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$", email))
like image 33
PyTis Avatar answered Oct 06 '22 01:10

PyTis


This is typically solved using regex. There are many variations of solutions however. Depending on how strict you need to be, and if you have custom requirements for validation, or will accept any valid email address.

See this page for reference: http://www.regular-expressions.info/email.html

like image 40
Gaute Løken Avatar answered Oct 06 '22 01:10

Gaute Løken


from validate_email import validate_email
is_valid = validate_email('[email protected]',verify=True)
print(bool(is_valid))

See validate_email docs.

like image 32
ali.etemadi77 Avatar answered Oct 06 '22 00:10

ali.etemadi77


import re
def email():
    email = raw_input("enter the mail address::")
     match = re.search(r'[\w.-]+@[\w.-]+.\w+', email)

    if match:
        print "valid email :::", match.group()
    else:
        print "not valid:::"

email()
like image 39
nidhin Avatar answered Oct 06 '22 01:10

nidhin


Email addresses are incredibly complicated. Here's a sample regex that will match every RFC822-valid address: http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html

You'll notice that it's probably longer than the rest of your program. There are even whole modules for Perl with the purpose of validating email addresses. So you probably won't get anything that's 100% perfect as a regex while also being readable. Here's a sample recursive descent parser: http://cpansearch.perl.org/src/ABIGAIL/RFC-RFC822-Address-2009110702/lib/RFC/RFC822/Address.pm

but you'll need to decide whether you need perfect parsing or simple code.

like image 28
Dan Avatar answered Oct 05 '22 23:10

Dan


If you want to take out the mail from a long string or file Then try this.

([^@|\s]+@[^@]+\.[^@|\s]+)

Note, this will work when you have a space before and after your email-address. if you don't have space or have some special chars then you may try modifying it.

Working example:

string="Hello ABCD, here is my mail id [email protected] "
res = re.search("([^@|\s]+@[^@]+\.[^@|\s]+)",string,re.I)
res.group(1)

This will take out [email protected] from this string.

Also, note this may not be the right answer... But I have posted it here to help someone who has specific requirement like me

like image 3
Raj Chinna Avatar answered Oct 05 '22 23:10

Raj Chinna


For check of email use email_validator

from email_validator import validate_email, EmailNotValidError

def check_email(email):
    try:
        v = validate_email(email)  # validate and get info
        email = v["email"]  # replace with normalized form
        print("True")
    except EmailNotValidError as e:
        # email is not valid, exception message is human-readable
        print(str(e))

check_email("test@gmailcom")
like image 1
Vladislav Koshenevskiy Avatar answered Oct 05 '22 23:10

Vladislav Koshenevskiy