Comparing E-mail Address Validating Regular Expressions

Updated: 9/24/2010

I wanted to find a regular expression to validate e-mail addresses, but when I searched I found dozens of slightly different versions of the same expression. Almost all of them had people leaving comments about how it failed to validate or invalidate some rare but completely valid/invalid address syntax. But dispite all the criticism, I couldn't find a definitive "best" expression. So, I setup arrays of some of the most promising expressions as well as a (hopefully) complete sampling of valid and invalid addresses. It's my philosophy that it's better to accept a few invalid addresses than reject any valid ones, so I'm shooting for 0 false-positives and as few false-negatives as possible.

Conclusion:
James Watts and Francisco Jose Martin Moreno are the first to develop one which passes all of the tests.
/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i

Arluison Guillaume has also improved Warren Gaebel's regex. This one will work in JavaScript:
/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i

Notes:

Results:

/^([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)$/i

James Watts and Francisco Jose Martin Moreno
Uses preg_match()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org valid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 valid
IPAndPort@127.0.0.1:25 valid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net valid
foor@bar.newTLD valid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org invalid

Valid: 19/19
Invalid: 18/18

/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD

http://pastie.textmate.org/159503
Uses preg_match()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org valid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 valid
IPAndPort@127.0.0.1:25 valid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net valid
foor@bar.newTLD valid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 19/19
Invalid: 17/18

/^(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){255,})(?!(?:(?:\x22?\x5C[\x00-\x7E]\x22?)|(?:\x22?[^\x5C\x22]\x22?)){65,}@)(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22))(?:\.(?:(?:[\x21\x23-\x27\x2A\x2B\x2D\x2F-\x39\x3D\x3F\x5E-\x7E]+)|(?:\x22(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|(?:\x5C[\x00-\x7F]))*\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\]))$/iD

http://svn.php.net/viewvc/php/php-src/trunk/ext/filter/logical_filters.c?view=markup
Uses preg_match()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org valid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 invalid
IPAndPort@127.0.0.1:25 invalid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net valid
foor@bar.newTLD valid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m valid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org invalid

Valid: 17/19
Invalid: 17/18

/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9]([-a-z0-9_]?[a-z0-9])*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z]{2})|([1]?\d{1,2}|2[0-4]{1}\d{1}|25[0-5]{1})(\.([1]?\d{1,2}|2[0-4]{1}\d{1}|25[0-5]{1})){3})(:[0-9]{1,5})?$/i

http://blog.tuxz.net/archives/2009/03/27/email_validation_using_regular_expression/
Uses preg_match()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org valid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 valid
IPAndPort@127.0.0.1:25 valid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net valid
foor@bar.newTLD invalid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 18/19
Invalid: 17/18

/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.([a-z][a-z]+)|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i

http://www.mi-ange.net/blog/msg.php?id=79&lng=en
Uses preg_match()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org valid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 valid
IPAndPort@127.0.0.1:25 valid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net valid
foor@bar.newTLD valid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com valid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 19/19
Invalid: 16/18

/\A[a-z0-9_+\-]+(\.[a-z0-9_+\-]+)*@([a-z0-9]+([a-z0-9]+|\.[a-z0-9]+|\-[a-z0-9]+)*\.(aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|[a-z]{2})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?\z/i

Brian Burns
Uses preg_match()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org invalid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 valid
IPAndPort@127.0.0.1:25 valid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net invalid
foor@bar.newTLD invalid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 16/19
Invalid: 17/18

/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_]+(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i

Warren Gaebel
Uses preg_match()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org valid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel invalid
uncommonTLD@domain.mobi invalid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 valid
IPAndPort@127.0.0.1:25 valid
subdomain@sub.domain.com valid
local@dash-inDomain.com invalid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net valid
foor@bar.newTLD invalid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 15/19
Invalid: 17/18

^([a-zA-Z0-9_'+*$%\^&!\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9:]{2,4})+$

My modification of Quirksmode.org regex
Uses eregi()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org valid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 invalid
IPAndPort@127.0.0.1:25 valid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net invalid
foor@bar.newTLD valid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: valid
invalid
someone-else@127.0.0.1.26 valid
.localStartsWithDot@domain.com valid
localEndsWithDot.@domain.com valid
two..consecutiveDots@domain.com valid
domainStartsWithDash@-domain.com valid
domainEndsWithDash@domain-.com valid
numbersInTLD@domain.c0m valid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 17/19
Invalid: 9/18

^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$

http://www.quirksmode.org/js/mailcheck.html
Uses eregi()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org invalid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 invalid
IPAndPort@127.0.0.1:25 invalid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net invalid
foor@bar.newTLD valid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 valid
.localStartsWithDot@domain.com valid
localEndsWithDot.@domain.com valid
two..consecutiveDots@domain.com valid
domainStartsWithDash@-domain.com valid
domainEndsWithDash@domain-.com valid
numbersInTLD@domain.c0m valid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 15/19
Invalid: 10/18

^[_a-zA-Z0-9-]+[@][a-zA-Z0-9]+[\.](com|net|org){1}$

My original attempt
Uses eregi()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org invalid
uncommonTLD@domain.museum invalid
uncommonTLD@domain.travel invalid
uncommonTLD@domain.mobi invalid
countryCodeTLD@domain.uk invalid
countryCodeTLD@domain.rw invalid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 invalid
IPAndPort@127.0.0.1:25 invalid
subdomain@sub.domain.com invalid
local@dash-inDomain.com invalid
dot.inLocal@foo.com invalid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net invalid
foor@bar.newTLD invalid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 6/19
Invalid: 17/18

^([A-Z0-9]+[._]?){1,}[A-Z0-9-]+\@(([A-Z0-9]+[-]?){1,}[A-Z0-9]+\.){1,}([A-Z]{2,4}|museum)$

http://aspn.activestate.com/ASPN/Cookbook/Rx/Recipe/59886
Uses eregi()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org invalid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel invalid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 invalid
IPAndPort@127.0.0.1:25 invalid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org invalid
singleLetterDomain@x.org invalid
&*=?^+{}'~@validCharsInLocal.net invalid
foor@bar.newTLD invalid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com invalid
localEndsWithDot.@domain.com invalid
two..consecutiveDots@domain.com invalid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 11/19
Invalid: 17/18

^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$

http://www.regular-expressions.info/email.html
Uses eregi()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org invalid
uncommonTLD@domain.museum invalid
uncommonTLD@domain.travel invalid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 invalid
IPAndPort@127.0.0.1:25 invalid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org valid
&*=?^+{}'~@validCharsInLocal.net invalid
foor@bar.newTLD invalid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com valid
localEndsWithDot.@domain.com valid
two..consecutiveDots@domain.com valid
domainStartsWithDash@-domain.com valid
domainEndsWithDash@domain-.com valid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 12/19
Invalid: 12/18

^[a-z0-9\._-]+@([a-z0-9][a-z0-9-]*[a-z0-9]\.)+([a-z]+\.)?([a-z]+)$

http://www.zend.com/zend/spotlight/code-gallery-wade5.php?article=code-gallery-wade5&kind=sl&id=1988&open=1&anc=0&view=1#Heading10
Uses eregi()
These should be valid
l3tt3rsAndNumb3rs@domain.com valid
has-dash@domain.com valid
hasApostrophe.o'leary@domain.org invalid
uncommonTLD@domain.museum valid
uncommonTLD@domain.travel valid
uncommonTLD@domain.mobi valid
countryCodeTLD@domain.uk valid
countryCodeTLD@domain.rw valid
lettersInDomain@911.com valid
underscore_inLocal@domain.net valid
IPInsteadOfDomain@127.0.0.1 invalid
IPAndPort@127.0.0.1:25 invalid
subdomain@sub.domain.com valid
local@dash-inDomain.com valid
dot.inLocal@foo.com valid
a@singleLetterLocal.org valid
singleLetterDomain@x.org invalid
&*=?^+{}'~@validCharsInLocal.net invalid
foor@bar.newTLD valid
 
These should be invalid
missingDomain@.com invalid
@missingLocal.org invalid
missingatSign.net invalid
missingDot@com invalid
two@@signs.com invalid
colonButNoPort@127.0.0.1: invalid
invalid
someone-else@127.0.0.1.26 invalid
.localStartsWithDot@domain.com valid
localEndsWithDot.@domain.com valid
two..consecutiveDots@domain.com valid
domainStartsWithDash@-domain.com invalid
domainEndsWithDash@domain-.com invalid
numbersInTLD@domain.c0m invalid
missingTLD@domain. invalid
! "#$%(),/;<>[]`|@invalidCharsInLocal.org invalid
invalidCharsInDomain@! "#$%(),/;<>_[]`|.org invalid
local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org valid

Valid: 14/19
Invalid: 14/18