if ($index > 64) return false; // Local part too long
$localPart = substr($email, 0, $index);
$domain = substr($email, $index + 1);
$domainLength = strlen($domain);
if ($domainLength === 0) return false; // No domain part
if ($domainLength > 255) return false; // Domain part too long
// Let's check the local part for RFC compliance...
//
// Period (".") may...appear, but may not be used to start or end the
// local part, nor may two or more consecutive periods appear.
// (http://tools.ietf.org/html/rfc3696#section-3)
if (preg_match('/^\\.|\\.\\.|\\.$/', $localPart) > 0) return false; // Dots in wrong place
// Any ASCII graphic (printing) character other than the
// at-sign ("@"), backslash, double quote, comma, or square brackets may
// appear without quoting. If any of that list of excluded characters
// are to appear, they must be quoted
// (http://tools.ietf.org/html/rfc3696#section-3)
if (preg_match('/^"(?:.)*"$/', $localPart) > 0) {
// Local part is a quoted string
if (preg_match('/(?:.)+[^\\\\]"(?:.)+/', $localPart) > 0) return false; // Unescaped quote
character inside quoted string
} else {
if (preg_match('/[ @\\[\\]\\\\",]/', $localPart) > 0)
// Check all excluded characters are escaped
$stripped = preg_replace('/\\\\[ @\\[\\]\\\\",]/', '', $localPart);
if (preg_match('/[ @\\[\\]\\\\",]/', $stripped) > 0) return false; // Unquoted excluded
characters
}
// Now let's check the domain part...
// The domain name can also be replaced by an IP address in square brackets
// (http://tools.ietf.org/html/rfc3696#section-3)
// (http://tools.ietf.org/html/rfc5321#section-4.1.3)
// (http://tools.ietf.org/html/rfc4291#section-2.2)
if (preg_match('/^\\[(.)+]$/', $domain) === 1) {
// It's an address-literal
$addressLiteral = substr($domain, 1, $domainLength - 2);
$matchesIP = array();