# a simplyfied email address check wrt. RFC2822 # i.e. # - display name is not supported # - obsolete specs are not honored # - [content] folding whitespaces are not allowed # AND # - quoted-string is not allowed (and thus no control characters) # - domain-literal is not allowed # so: atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" dot-atom-text = 1*atext *("." 1*atext) dot-atom = dot-atom-text qtext = NO-WS-CTL / %d33 / %d35-91 / %d93-126 text = %d1-9 / %d11 / %d12 / %d14-127 quoted-pair = "\" text qcontent = qtext / quoted-pair quoted-string = DQUOTE *qcontent DQUOTE local-part = dot-atom / quoted-string NO-WS-CTL = %d1-8 / %d11 / %d12 / %d14-31 / %d127 dtext = NO-WS-CTL / %d33-90 / %d94-126 dcontent = dtext / quoted-pair domain-literal = "[" *dcontent "]" domain = dot-atom / domain-literal addr-spec = local-part "@" domain DQUOTE = %d34 text = %d1-9 / %d11 / %d12 / %d14-127 # gets reduced to atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" dot-atom-text = 1*atext *("." 1*atext) dot-atom = dot-atom-text local-part = dot-atom domain = dot-atom addr-spec = local-part "@" domain = dot-atom "@" dot-atom # which yields e.g. to: #Java: static final String atext = "[\\p{Graph}&&[^\"(),.:;<>@\\[\\]]]"; static final Pattern dotatom = Pattern.compile("^" + atext + "+(?:\\." + atext + "+)*$"); public final String checkEmailAddr(String addr) { if (addr == null) { return "null address"; } int idx = addr.indexOf('@'); if (idx == -1) { return "invalid address"; } String localPart = addr.substring(0,idx); Matcher matcher = dotatom.matcher(localPart); if (!matcher.matches()) { return "unsupported local-part '" + localPart + "'"; } String domain = addr.substring(idx+1); matcher.reset(domain); if (!matcher.matches()) { return "unsupported domain '" + domain + "'"; } return checkDomain(domain); } # RFC 1035 + 1101 let-dig = ALPHA / DIGIT let-dig-hyp = let-dig / "-" label = let-dig *( *let-dig-hyp let-dig) subdomain = label *("." label) domain = subdomain / " " static final Pattern domainLabelPattern = "^[\\p{Alpha}\\p{Digit}]+(?:-+[\\p{Alpha}\\p{Digit}]+)*$"; public final String checkDomain(String domain) { if (domain.length() > 255) { return "Domain too long"; } String[] label = domain.split("\\."); // we require to have at least two labels and the last two ones must have // at least 2 characters int count = label.length-1; if (count < 1 || label[count].length() < 2 || label[count-1].length() < 2) { return "invalid domain"; } Matcher m = domainLabelPattern.matcher(""); for (count; count >= 0; count--) { if (label[count].length > 63) { return "label too long"; } m.reset(label[count]); if (!m.matches()) { return "invalid domain"; } } // everything else wrt. domain should be checked via CIDR return null; } OR Javascript: function checkemail(str) { var idx = str.indexOf("@"); if (idx == -1) { return false; } var localPart = str.substr(0,idx); // var atext = "[a-zA-Z0-9!#$%&'*+-/=?^_`{|}~]"; // "^" + atext + "+(?:\." + atext + "+)*$" var dotatom = /^[-a-zA-Z0-9!#$%&'*+/=?^_`{|}~]+(?:\.[-a-zA-Z0-9!#$%&'*+/=?^_`{|}~]+)*$/ ; // even more simplified to avoid trouble with other languages // var dotatom = /^[-a-zA-Z0-9%&+=?_~]+(?:\.[-a-zA-Z0-9%&+=?_~]+)*$/ ; if (!dotatom.test(localPart)) { return false; } var domain = str.substr(idx+1); if (!dotatom.test(domain)) { return false; } if (domain.length > 255) { return false; // domain too long } var label = domain.split("\."); var count = label.length-1; if (count < 1 || label[count].length < 2 || label[count-1].length < 2) { return false; // top and 2nd level domain too short } var domainLabel = /^[a-zA-Z0-9]+(?:-+[a-zA-Z0-9]+)*$/; for (; count >= 0; count--) { if (label[count].length > 63) { return false; // subdomain too long } if (!domainLabel.test(label[count])) { return false; // invalid characters } } // even if numerical IPs are allowed, we choose to not accept them and avoid // CIDR check var tldIP = /[0-9]+$/ ; var allIP = /^[0-9]+(?:\.[0-9]+)*$/ ; if (tldIP.test(domain) || allIP.test(domain)) { return false; } return true; }