什么是最好的Java电子邮件地址validation方法?

Java有什么好的电子邮件地址validation库? 是否有任何替代commonsvalidation程序 ?

Apache Commons通常被称为一个坚实的项目。 请记住,如果你想确保它是一个真正的电子邮件,并且所有者希望它在你的网站上使用,你仍然必须发送一个validation邮件到这个地址。

编辑 :有一个错误 ,它在域上太严格,导致它不接受新的顶级域名有效的电子邮件。

这个bug在03 / Jan / 15 02:48在commons-validator 1.4.1版本中解决了

使用官方的Java电子邮件包是最简单的:

 public static boolean isValidEmailAddress(String email) { boolean result = true; try { InternetAddress emailAddr = new InternetAddress(email); emailAddr.validate(); } catch (AddressException ex) { result = false; } return result; } 

Apache Commonsvalidation器可以像其他答案中提到的那样使用。

pom.xml中:

 <dependency> <groupId>commons-validator</groupId> <artifactId>commons-validator</artifactId> <version>1.4.1</version> </dependency> 

的build.gradle:

 compile 'commons-validator:commons-validator:1.4.1' 

import:

 import org.apache.commons.validator.routines.EmailValidator; 

代码:

 String email = "myName@example.com"; boolean valid = EmailValidator.getInstance().isValid(email); 

并允许本地地址

 boolean allowLocal = true; boolean valid = EmailValidator.getInstance(allowLocal).isValid(email); 

迟到的答案,但我认为这是简单而值得的:

  public boolean isValidEmailAddress(String email) { String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$"; java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern); java.util.regex.Matcher m = p.matcher(email); return m.matches(); } 

testing案例

在这里输入图像描述

出于生产目的,应该以networking方式执行域名validation。

如果你正在尝试从客户端收到表单validation,或者只是一个beanvalidation – 保持简单。 最好做一个宽松的电子邮件validation,而不是做一个严格的电子邮件validation,拒绝一些人(例如,当他们正在尝试注册您的Web服务)。 几乎所有邮件的用户名部分都允许使用,并且每个月都会增加许多新的域名(例如.company,.entreprise,.estate),所以不会受到限制:

 Pattern pattern = Pattern.compile("^.+@.+\\..+$"); Matcher matcher = pattern.matcher(email); 

我只是想知道为什么没有人从Hibernate Validator的附加约束中得到@Email 。 validation器本身是EmailValidator

Les Hazlewood使用Java正则expression式编写了一个非常彻底的符合RFC 2822的电子邮件validation程序类。 你可以在http://www.leshazlewood.com/?p=23find它。; 然而,其彻底性(或Java RE实现)导致效率低下 – 阅读关于parsing长地址的时间的评论。

问题迟了,在这里,但是:我在这个地址保持一个类: http : //lacinato.com/cm/software/emailrelated/emailaddress

它基于Les Hazlewood的课程,但有许多改进,并修复了一些错误。 Apache许可证。

我相信这是Java中function最强大的电子邮件parsing器,而且我还没有看到任何一种语言的function,尽pipe可能有一种语言。 这不是一个词法分析器式的parsing器,但是使用了一些复杂的java正则expression式,因此效率不如以前,但是我的公司已经用它parsing了超过100亿个真实世界的地址:它当然可用于高性能情况。 也许一年一次,它会碰到一个导致正则expression式堆栈溢出的地址(适当地),但是这些地址是数百或数千个字符的垃圾地址,带有许多引号和括号等。

RFC 2822和相关规范在电子邮件地址方面确实相当宽容,所以像这样的类对于大多数用途来说是过分的。 例如,以下是一个合法的地址,根据规格,空间和所有:

 "<bob \" (here) " < (hi there) "bob(the man)smith" (hi) @ (there) example.com (hello) > (again) 

没有邮件服务器会允许这个,但是这个类可以parsing它(并且把它重写成一个可用的forms)。

我们发现现有的Java电子邮件parsing器选项是不够持久的(也就是说,他们都不能parsing一些有效的地址),所以我们创build了这个类。

该代码是有据可查的,并有许多易于更改的选项来允许或禁止某些电子邮件表单。 它还提供了许多方法来访问地址的某些部分(左侧,右侧,个人名称,注释等),parsing/validation邮箱列表头,parsing/validation返回path(在标题中是唯一的)等等。

所写的代码具有javamail依赖性,但是如果您不想要它提供的次要function,则很容易将其删除。

我在Zend_Validator_Email中移植了一些代码:

 @FacesValidator("emailValidator") public class EmailAddressValidator implements Validator { private String localPart; private String hostName; private boolean domain = true; Locale locale; ResourceBundle bundle; private List<FacesMessage> messages = new ArrayList<FacesMessage>(); private HostnameValidator hostnameValidator; @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { setOptions(component); String email = (String) value; boolean result = true; Pattern pattern = Pattern.compile("^(.+)@([^@]+[^.])$"); Matcher matcher = pattern.matcher(email); locale = context.getViewRoot().getLocale(); bundle = ResourceBundle.getBundle("com.myapp.resources.validationMessages", locale); boolean length = true; boolean local = true; if (matcher.find()) { localPart = matcher.group(1); hostName = matcher.group(2); if (localPart.length() > 64 || hostName.length() > 255) { length = false; addMessage("enterValidEmail", "email.AddressLengthExceeded"); } if (domain == true) { hostnameValidator = new HostnameValidator(); hostnameValidator.validate(context, component, hostName); } local = validateLocalPart(); if (local && length) { result = true; } else { result = false; } } else { result = false; addMessage("enterValidEmail", "invalidEmailAddress"); } if (result == false) { throw new ValidatorException(messages); } } private boolean validateLocalPart() { // First try to match the local part on the common dot-atom format boolean result = false; // Dot-atom characters are: 1*atext *("." 1*atext) // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*", // "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~" String atext = "a-zA-Z0-9\\u0021\\u0023\\u0024\\u0025\\u0026\\u0027\\u002a" + "\\u002b\\u002d\\u002f\\u003d\\u003f\\u005e\\u005f\\u0060\\u007b" + "\\u007c\\u007d\\u007e"; Pattern regex = Pattern.compile("^["+atext+"]+(\\u002e+["+atext+"]+)*$"); Matcher matcher = regex.matcher(localPart); if (matcher.find()) { result = true; } else { // Try quoted string format // Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE // qtext: Non white space controls, and the rest of the US-ASCII characters not // including "\" or the quote character String noWsCtl = "\\u0001-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f"; String qText = noWsCtl + "\\u0021\\u0023-\\u005b\\u005d-\\u007e"; String ws = "\\u0020\\u0009"; regex = Pattern.compile("^\\u0022(["+ws+qText+"])*["+ws+"]?\\u0022$"); matcher = regex.matcher(localPart); if (matcher.find()) { result = true; } else { addMessage("enterValidEmail", "email.AddressDotAtom"); addMessage("enterValidEmail", "email.AddressQuotedString"); addMessage("enterValidEmail", "email.AddressInvalidLocalPart"); } } return result; } private void addMessage(String detail, String summary) { String detailMsg = bundle.getString(detail); String summaryMsg = bundle.getString(summary); messages.add(new FacesMessage(FacesMessage.SEVERITY_ERROR, summaryMsg, detailMsg)); } private void setOptions(UIComponent component) { Boolean domainOption = Boolean.valueOf((String) component.getAttributes().get("domain")); //domain = (domainOption == null) ? true : domainOption.booleanValue(); } } 

使用主机名validation程序如下:

 @FacesValidator("hostNameValidator") public class HostnameValidator implements Validator { private Locale locale; private ResourceBundle bundle; private List<FacesMessage> messages; private boolean checkTld = true; private boolean allowLocal = false; private boolean allowDNS = true; private String tld; private String[] validTlds = {"ac", "ad", "ae", "aero", "af", "ag", "ai", "al", "am", "an", "ao", "aq", "ar", "arpa", "as", "asia", "at", "au", "aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz", "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca", "cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co", "com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk", "dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi", "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw", "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in", "info", "int", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jobs", "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma", "mc", "md", "me", "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo", "mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx", "my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni", "nl", "no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph", "pk", "pl", "pm", "pn", "pr", "pro", "ps", "pt", "pw", "py", "qa", "re", "ro", "rs", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si", "sj", "sk", "sl", "sm", "sn", "so", "sr", "st", "su", "sv", "sy", "sz", "tc", "td", "tel", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to", "tp", "tr", "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um", "us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws", "ye", "yt", "yu", "za", "zm", "zw"}; private Map<String, Map<Integer, Integer>> idnLength; private void init() { Map<Integer, Integer> biz = new HashMap<Integer, Integer>(); biz.put(5, 17); biz.put(11, 15); biz.put(12, 20); Map<Integer, Integer> cn = new HashMap<Integer, Integer>(); cn.put(1, 20); Map<Integer, Integer> com = new HashMap<Integer, Integer>(); com.put(3, 17); com.put(5, 20); Map<Integer, Integer> hk = new HashMap<Integer, Integer>(); hk.put(1, 15); Map<Integer, Integer> info = new HashMap<Integer, Integer>(); info.put(4, 17); Map<Integer, Integer> kr = new HashMap<Integer, Integer>(); kr.put(1, 17); Map<Integer, Integer> net = new HashMap<Integer, Integer>(); net.put(3, 17); net.put(5, 20); Map<Integer, Integer> org = new HashMap<Integer, Integer>(); org.put(6, 17); Map<Integer, Integer> tw = new HashMap<Integer, Integer>(); tw.put(1, 20); Map<Integer, Integer> idn1 = new HashMap<Integer, Integer>(); idn1.put(1, 20); Map<Integer, Integer> idn2 = new HashMap<Integer, Integer>(); idn2.put(1, 20); Map<Integer, Integer> idn3 = new HashMap<Integer, Integer>(); idn3.put(1, 20); Map<Integer, Integer> idn4 = new HashMap<Integer, Integer>(); idn4.put(1, 20); idnLength = new HashMap<String, Map<Integer, Integer>>(); idnLength.put("BIZ", biz); idnLength.put("CN", cn); idnLength.put("COM", com); idnLength.put("HK", hk); idnLength.put("INFO", info); idnLength.put("KR", kr); idnLength.put("NET", net); idnLength.put("ORG", org); idnLength.put("TW", tw); idnLength.put("ایران", idn1); idnLength.put("中国", idn2); idnLength.put("公司", idn3); idnLength.put("networking", idn4); messages = new ArrayList<FacesMessage>(); } public HostnameValidator() { init(); } @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { String hostName = (String) value; locale = context.getViewRoot().getLocale(); bundle = ResourceBundle.getBundle("com.myapp.resources.validationMessages", locale); Pattern ipPattern = Pattern.compile("^[0-9a-f:\\.]*$", Pattern.CASE_INSENSITIVE); Matcher ipMatcher = ipPattern.matcher(hostName); if (ipMatcher.find()) { addMessage("hostname.IpAddressNotAllowed"); throw new ValidatorException(messages); } boolean result = false; // removes last dot (.) from hostname hostName = hostName.replaceAll("(\\.)+$", ""); String[] domainParts = hostName.split("\\."); boolean status = false; // Check input against DNS hostname schema if ((domainParts.length > 1) && (hostName.length() > 4) && (hostName.length() < 255)) { status = false; dowhile: do { // First check TLD int lastIndex = domainParts.length - 1; String domainEnding = domainParts[lastIndex]; Pattern tldRegex = Pattern.compile("([^.]{2,10})", Pattern.CASE_INSENSITIVE); Matcher tldMatcher = tldRegex.matcher(domainEnding); if (tldMatcher.find() || domainEnding.equals("ایران") || domainEnding.equals("中国") || domainEnding.equals("公司") || domainEnding.equals("networking")) { // Hostname characters are: *(label dot)(label dot label); max 254 chars // label: id-prefix [*ldh{61} id-prefix]; max 63 chars // id-prefix: alpha / digit // ldh: alpha / digit / dash // Match TLD against known list tld = (String) tldMatcher.group(1).toLowerCase().trim(); if (checkTld == true) { boolean foundTld = false; for (int i = 0; i < validTlds.length; i++) { if (tld.equals(validTlds[i])) { foundTld = true; } } if (foundTld == false) { status = false; addMessage("hostname.UnknownTld"); break dowhile; } } /** * Match against IDN hostnames * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames */ List<String> regexChars = getIdnRegexChars(); // Check each hostname part int check = 0; for (String domainPart : domainParts) { // Decode Punycode domainnames to IDN if (domainPart.indexOf("xn--") == 0) { domainPart = decodePunycode(domainPart.substring(4)); } // Check dash (-) does not start, end or appear in 3rd and 4th positions if (domainPart.indexOf("-") == 0 || (domainPart.length() > 2 && domainPart.indexOf("-", 2) == 2 && domainPart.indexOf("-", 3) == 3) || (domainPart.indexOf("-") == (domainPart.length() - 1))) { status = false; addMessage("hostname.DashCharacter"); break dowhile; } // Check each domain part boolean checked = false; for (int key = 0; key < regexChars.size(); key++) { String regexChar = regexChars.get(key); Pattern regex = Pattern.compile(regexChar); Matcher regexMatcher = regex.matcher(domainPart); status = regexMatcher.find(); if (status) { int length = 63; if (idnLength.containsKey(tld.toUpperCase()) && idnLength.get(tld.toUpperCase()).containsKey(key)) { length = idnLength.get(tld.toUpperCase()).get(key); } int utf8Length; try { utf8Length = domainPart.getBytes("UTF8").length; if (utf8Length > length) { addMessage("hostname.InvalidHostname"); } else { checked = true; break; } } catch (UnsupportedEncodingException ex) { Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex); } } } if (checked) { ++check; } } // If one of the labels doesn't match, the hostname is invalid if (check != domainParts.length) { status = false; addMessage("hostname.InvalidHostnameSchema"); } } else { // Hostname not long enough status = false; addMessage("hostname.UndecipherableTld"); } } while (false); if (status == true && allowDNS) { result = true; } } else if (allowDNS == true) { addMessage("hostname.InvalidHostname"); throw new ValidatorException(messages); } // Check input against local network name schema; Pattern regexLocal = Pattern.compile("^(([a-zA-Z0-9\\x2d]{1,63}\\x2e)*[a-zA-Z0-9\\x2d]{1,63}){1,254}$", Pattern.CASE_INSENSITIVE); boolean checkLocal = regexLocal.matcher(hostName).find(); if (allowLocal && !status) { if (checkLocal) { result = true; } else { // If the input does not pass as a local network name, add a message result = false; addMessage("hostname.InvalidLocalName"); } } // If local network names are not allowed, add a message if (checkLocal && !allowLocal && !status) { result = false; addMessage("hostname.LocalNameNotAllowed"); } if (result == false) { throw new ValidatorException(messages); } } private void addMessage(String msg) { String bundlMsg = bundle.getString(msg); messages.add(new FacesMessage(FacesMessage.SEVERITY_ERROR, bundlMsg, bundlMsg)); } /** * Returns a list of regex patterns for the matched TLD * @param tld * @return */ private List<String> getIdnRegexChars() { List<String> regexChars = new ArrayList<String>(); regexChars.add("^[a-z0-9\\x2d]{1,63}$"); Document doc = null; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); try { InputStream validIdns = getClass().getClassLoader().getResourceAsStream("com/myapp/resources/validIDNs_1.xml"); DocumentBuilder builder = factory.newDocumentBuilder(); doc = builder.parse(validIdns); doc.getDocumentElement().normalize(); } catch (SAXException ex) { Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex); } catch (ParserConfigurationException ex) { Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex); } // prepare XPath XPath xpath = XPathFactory.newInstance().newXPath(); NodeList nodes = null; String xpathRoute = "//idn[tld=\'" + tld.toUpperCase() + "\']/pattern/text()"; try { XPathExpression expr; expr = xpath.compile(xpathRoute); Object res = expr.evaluate(doc, XPathConstants.NODESET); nodes = (NodeList) res; } catch (XPathExpressionException ex) { Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex); } for (int i = 0; i < nodes.getLength(); i++) { regexChars.add(nodes.item(i).getNodeValue()); } return regexChars; } /** * Decode Punycode string * @param encoded * @return */ private String decodePunycode(String encoded) { Pattern regex = Pattern.compile("([^a-z0-9\\x2d]{1,10})", Pattern.CASE_INSENSITIVE); Matcher matcher = regex.matcher(encoded); boolean found = matcher.find(); if (encoded.isEmpty() || found) { // no punycode encoded string, return as is addMessage("hostname.CannotDecodePunycode"); throw new ValidatorException(messages); } int separator = encoded.lastIndexOf("-"); List<Integer> decoded = new ArrayList<Integer>(); if (separator > 0) { for (int x = 0; x < separator; ++x) { decoded.add((int) encoded.charAt(x)); } } else { addMessage("hostname.CannotDecodePunycode"); throw new ValidatorException(messages); } int lengthd = decoded.size(); int lengthe = encoded.length(); // decoding boolean init = true; int base = 72; int index = 0; int ch = 0x80; int indexeStart = (separator == 1) ? (separator + 1) : 0; for (int indexe = indexeStart; indexe < lengthe; ++lengthd) { int oldIndex = index; int pos = 1; for (int key = 36; true; key += 36) { int hex = (int) encoded.charAt(indexe++); int digit = (hex - 48 < 10) ? hex - 22 : ((hex - 65 < 26) ? hex - 65 : ((hex - 97 < 26) ? hex - 97 : 36)); index += digit * pos; int tag = (key <= base) ? 1 : ((key >= base + 26) ? 26 : (key - base)); if (digit < tag) { break; } pos = (int) (pos * (36 - tag)); } int delta = (int) (init ? ((index - oldIndex) / 700) : ((index - oldIndex) / 2)); delta += (int) (delta / (lengthd + 1)); int key; for (key = 0; delta > 910; key += 36) { delta = (int) (delta / 35); } base = (int) (key + 36 * delta / (delta + 38)); init = false; ch += (int) (index / (lengthd + 1)); index %= (lengthd + 1); if (lengthd > 0) { for (int i = lengthd; i > index; i--) { decoded.set(i, decoded.get(i - 1)); } } decoded.set(index++, ch); } // convert decoded ucs4 to utf8 string StringBuilder sb = new StringBuilder(); for (int i = 0; i < decoded.size(); i++) { int value = decoded.get(i); if (value < 128) { sb.append((char) value); } else if (value < (1 << 11)) { sb.append((char) (192 + (value >> 6))); sb.append((char) (128 + (value & 63))); } else if (value < (1 << 16)) { sb.append((char) (224 + (value >> 12))); sb.append((char) (128 + ((value >> 6) & 63))); sb.append((char) (128 + (value & 63))); } else if (value < (1 << 21)) { sb.append((char) (240 + (value >> 18))); sb.append((char) (128 + ((value >> 12) & 63))); sb.append((char) (128 + ((value >> 6) & 63))); sb.append((char) (128 + (value & 63))); } else { addMessage("hostname.CannotDecodePunycode"); throw new ValidatorException(messages); } } return sb.toString(); } /** * Eliminates empty values from input array * @param data * @return */ private String[] verifyArray(String[] data) { List<String> result = new ArrayList<String>(); for (String s : data) { if (!s.equals("")) { result.add(s); } } return result.toArray(new String[result.size()]); } } 

和一个validIDNs.xml与正则expression式模式为不同的tlds(太大,包括:)

 <idnlist> <idn> <tld>AC</tld> <pattern>^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$</pattern> </idn> <idn> <tld>AR</tld> <pattern>^[\u002d0-9a-zà-ãç-êìíñ-õü]{1,63}$</pattern> </idn> <idn> <tld>AS</tld> <pattern>/^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$</pattern> </idn> <idn> <tld>AT</tld> <pattern>/^[\u002d0-9a-zà-öø-ÿœšž]{1,63}$</pattern> </idn> <idn> <tld>BIZ</tld> <pattern>^[\u002d0-9a-zäåæéöøü]{1,63}$</pattern> <pattern>^[\u002d0-9a-záéíñóúü]{1,63}$</pattern> <pattern>^[\u002d0-9a-záéíóöúüőű]{1,63}$</pattern> </id> </idlist> 
 public class Validations { private Pattern regexPattern; private Matcher regMatcher; public String validateEmailAddress(String emailAddress) { regexPattern = Pattern.compile("^[(a-zA-Z-0-9-\\_\\+\\.)]+@[(azAz)]+\\.[(a-zA-z)]{2,3}$"); regMatcher = regexPattern.matcher(emailAddress); if(regMatcher.matches()) { return "Valid Email Address"; } else { return "Invalid Email Address"; } } public String validateMobileNumber(String mobileNumber) { regexPattern = Pattern.compile("^\\+[0-9]{2,3}+-[0-9]{10}$"); regMatcher = regexPattern.matcher(mobileNumber); if(regMatcher.matches()) { return "Valid Mobile Number"; } else { return "Invalid Mobile Number"; } } public static void main(String[] args) { String emailAddress = "suryaprakash.pisay@gmail.com"; String mobileNumber = "+91-9986571622"; Validations validations = new Validations(); System.out.println(validations.validateEmailAddress(emailAddress)); System.out.println(validations.validateMobileNumber(mobileNumber)); } } 

你想validation什么? 电子邮件地址?

电子邮件地址只能检查其格式一致性。 请参阅标准: RFC2822 。 最好的方法是正则expression式。 你永远不会知道如果真的存在没有发送电子邮件。

我检查了commonsvalidation器。 它包含一个org.apache.commons.validator.EmailValidator类。 似乎是一个很好的起点。

目前的Apache Commons Validator版本是1.3.1 。

validation的类是org.apache.commons.validator.EmailValidator。 它有一个来自雅加达退休ORO项目的 org.apache.oro.text.perl.Perl5Util的导入 。

顺便说一句,我发现有一个1.4版本, 这里是API文档 。 在网站上写着:“上次发布时间:2008年3月5日|版本:1.4-SNAPSHOT”,但这不是最终的。 只有build立自己的方式(但这是一个快照,而不是释放),并使用,或从这里下载。 这意味着1.4年还没有最终三年(2008-2011)。 这不是Apache的风格。 我正在寻找一个更好的select,但没有find一个非常通过。 我想要使​​用经过很好testing的东西,不想碰到任何错误。

如果你想validation一个电子邮件地址是否有效,那么VRFY会给你一些方法。 我发现它对validation内部网地址(即内部站点的电子邮件地址)很有用。 但是它对于互联网邮件服务器来说不是很有用(见本页顶部的注意事项)

你也可能要检查长度 – 电子邮件最长为254个字符。 我使用的Apache公共validation器,它不检查这一点。

这是最好的方法:

 public static boolean isValidEmail(String enteredEmail){ String EMAIL_REGIX = "^[\\\\w!#$%&'*+/=?`{|}~^-]+(?:\\\\.[\\\\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\\\.)+[a-zA-Z]{2,6}$"; Pattern pattern = Pattern.compile(EMAIL_REGIX); Matcher matcher = pattern.matcher(enteredEmail); return ((!enteredEmail.isEmpty()) && (enteredEmail!=null) && (matcher.matches())); } 

来源: – http://howtodoinjava.com/2014/11/11/java-regex-validate-email-address/

http://www.rfc-editor.org/rfc/rfc5322.txt

似乎没有任何完美的库或方法可以自己做到这一点,除非你有时间发送电子邮件到电子邮件地址,并等待回应(这可能不是一个选项)。 我结束了从这里使用一个build议http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/和调整代码,所以它可以在Java中工作。;

 public static boolean isValidEmailAddress(String email) { boolean stricterFilter = true; String stricterFilterString = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; String laxString = ".+@.+\\.[A-Za-z]{2}[A-Za-z]*"; String emailRegex = stricterFilter ? stricterFilterString : laxString; java.util.regex.Pattern p = java.util.regex.Pattern.compile(emailRegex); java.util.regex.Matcher m = p.matcher(email); return m.matches(); } 

下面是我的实用方法,我只想使用RFC中允许的字符来合理区分blah @ domain地址。 地址必须事先转换为小写。

 public class EmailAddressValidator { private static final String domainChars = "a-z0-9\\-"; private static final String atomChars = "a-z0-9\\Q!#$%&'*+-/=?^_`{|}~\\E"; private static final String emailRegex = "^" + dot(atomChars) + "@" + dot(domainChars) + "$"; private static final Pattern emailPattern = Pattern.compile(emailRegex); private static String dot(String chars) { return "[" + chars + "]+(?:\\.[" + chars + "]+)*"; } public static boolean isValidEmailAddress(String address) { return address != null && emailPattern.matcher(address).matches(); } } 

| * | Simple Check if email is valid :

 static boolean isValidEmailAddress(String emailVar) { String mylRegExpVar = "[A-Za-z0-9._%+-]{2,}+@[A-Za-z-]{2,}+\\.[A-Za-z]{2,}"; Pattern pVar = Pattern.compile(mylRegExpVar); Matcher mVar = pVar.matcher(emailVar); return mVar.matches(); } 

I use regex for this:

  /** * Check if an E-Mail Adress is valid, the rules are: * <p><ul> * <li>1: 1-64 digit: the localpart myemail(@web.de) contains only the chars * 'A-Za-z0-9.!#$%&'*+-/=?^_`{|}~'. * <li>2: 1-255 digit: It contains a '@' followed by the sub domain name wich * contains only the chars '0-9a-zA-Z'. * <li>3: 1-10 digit: Then follows a '.' followed by the main domain wich * contains only the chars '0-9a-zA-Z'. * <li>4: The full lengh of the E-Mail is under 321 chars. * <li>The rules are * mainly defined by the 'Internet Message Format' (RFC 5332). * </ul><p> * * @param mail - The E-Mail adress. * @return True if the E-Mail is valid, otherwise false. */ public static boolean isValidEmail(String mail) { return (mail.matches("^[0-9a-zA-Z!#$%&;'*+\\-/\\=\\?\\^_`\\.{|}~]{1,64}@[0-9a-zA-Z]{1,255}\\.[a-zA-Z]{1,10}") && mail.length() <= 320); } 
 public void EmailCheck(View v) // This is pattern method import by regular class { String str = ""; emailid = emailID.getText().toString(); if(emailid.equalsIgnoreCase(str)) { System.out.println("Please enter your email id"); } else { Pattern p =Pattern.compile("[a-zA-Z0-9_.]*@[a-zA-Z]*.[a-zA-Z]*"); Matcher m = p.matcher(emailid); boolean bm = m.matches(); if(bm == true) { System.out.println("email id is valid"); } else { System.out.println("email id is Invalid, Re-try again"); } } } 

This is the simplest way to do it, without any regular expressions or Object-Armageddon.

"ABC.DEF@GHI.JKL" = 0

" ABC.DEF@GHI.JKL " = 0 vorlaufende und nachlaufende Leerzeichen werden unterdrueckt

"ABC_HH@T-OFFLINE.DE" = 0 Zeichen "_" und "-" duerfen vorkommen

"A@B.CD" = 0 minimal gueltige Laenge sind 6 Zeichen

"ABC.DEF@@GHI.JKL" = 11 doppeltes AT-Zeichen

".ABC.DEF@GHI.JKL" = 5 Start auf .

"ABC.DEF@GHI.JKL." = 16 Ende auf .

"ABCDEF@GHIJKL" = 13 Keinen Punkt gefunden

"ABC.DEF.@GHI.JKL" = 10 .@

"ABC.DEF@.GHI.JKL" = 9 @.

"ABC.DEF@7HI.JKL" = 3 Zahl nach dem AT-Zeichen

"ABC.DEF@_HI.JKL" = 3 Sonderzeichen nach dem AT-Zeichen

"ABC.DEF@GHI..JKL" = 4 keine 2 Punkte nacheinander

"ABC.DEF@" = 8 kein AT-Zeichen am Ende

"ABC.DEF@GHI.J" = 17 Top-Level-Domain muss 2 Stellen haben

null = 1 Eingabestring nicht gesetzt

" " = 2 durch TRIM eine Laenge von 0

" A . B & C . D " = 12 Leerzeichen innerhalb der eMail-Adresse

"(?).[!]@{&}.: " = 12 Sonderzeichen sind nicht erlaubt

  public static int checkEMailAdresse( String pEingabe ) { if ( pEingabe == null ) return 1; // Eingabe ist null String pruef_str = pEingabe.trim(); int len_pruef_str = pruef_str.length(); if ( ( len_pruef_str < 6 ) || ( len_pruef_str > 254 ) ) return 2; // Laengenbegrenzungen int pos_at_zeichen = -1; int letzter_punkt = -1; int zeichen_zaehler = 0; int akt_index = 0; while ( akt_index < len_pruef_str ) { char aktuelles_zeichen = pruef_str.charAt( akt_index ); if ( ( ( aktuelles_zeichen >= 'a' ) && ( aktuelles_zeichen <= 'z' ) ) || ( ( aktuelles_zeichen >= 'A' ) && ( aktuelles_zeichen <= 'Z' ) ) ) { zeichen_zaehler++; } else if ( ( ( aktuelles_zeichen >= '0' ) && ( aktuelles_zeichen <= '9' ) ) || ( aktuelles_zeichen == '_' ) || ( aktuelles_zeichen == '-' ) ) { if ( zeichen_zaehler == 0 ) return 3; // Zahl oder Sonderzeichen nur nach einem Zeichen hinter ABC (Teilstring darf nicht mit Zahl oder Sonderzeichen beginnen) } else if ( aktuelles_zeichen == '.' ) { if ( letzter_punkt == -1 ) { if ( akt_index == 0 ) return 5; // kein Beginn mit einem Punkt } else { if ( akt_index - letzter_punkt == 1 ) return 4; // keine zwei Punkte hintereinander } letzter_punkt = akt_index; zeichen_zaehler = 0; } else if ( aktuelles_zeichen == '@' ) { if ( pos_at_zeichen == -1 ) { if ( akt_index == 0 ) return 6; // kein AT-Zeichen am Anfang if ( akt_index > 64 ) return 7; // RFC 5321 ==> SMTP-Protokoll ==> maximale Laenge des Local-Parts sind 64 Bytes if ( ( akt_index + 1 ) == len_pruef_str ) return 8; // kein AT-Zeichen am Ende if ( akt_index - letzter_punkt == 1 ) return 10; // ungueltige Zeichenkombination ".@" if ( pruef_str.charAt( akt_index + 1 ) == '.' ) return 9; // ungueltige Zeichenkombination "@." pos_at_zeichen = akt_index; zeichen_zaehler = 0; } else { return 11; // kein weiteres AT-Zeichen zulassen, wenn schon AT-Zeichen gefunden wurde } } else { return 12; // ungueltiges Zeichen in der Eingabe gefunden } akt_index++; } if ( letzter_punkt == -1 ) return 13; // keinen Punkt gefunden (Es muss mindestens ein Punkt fuer den Domain-Trenner vorhanden sein) if ( pos_at_zeichen == -1 ) return 14; // kein AT-Zeichen gefunden if ( letzter_punkt < pos_at_zeichen ) return 15; // der letzte Punkt muss nach dem AT-Zeichen liegen (... hier eben die negative Form, wenn der letzte Punkt vor dem AT-Zeichen stand ist es ein Fehler) if ( ( letzter_punkt + 1 ) == len_pruef_str ) return 16; // der letzte Punkt darf nicht am Ende liegen if ( ( letzter_punkt + 1 ) > ( len_pruef_str - 2 ) ) return 17; // Top-Level-Domain muss mindestens 2 Stellen lang sein. return 0; } 

/*to validate email id without using regex and packages and followed by your validate symbol and domain extensions u can add … on below try1,holly methods */

 import java.util.Scanner; public test extends Exception { } public class demo extends test { public static boolean try1(char s) { boolean k = false; char[] d={'-','_','.'};//add valid Symbols for(int i=0;i<d.length;i++) { if( s==d[i]) { k=true; } } return k; } public static boolean holly(String s) throws test { int i=s.lastIndexOf("."); int j=s.length(); String o=s.substring(i+1,j); boolean d=false; String[] g={"co","in","com","org","net"};//add domain name extenstions for(int k=0;k<g.length;k++) { if(g[k].equals(o)) { d=true; } } if(d==false) { throw new test(); } return d; } public static void main(String[] args) { try { Scanner s=new Scanner(System.in); System.out.println("enter the email no of.id "); int n=s.nextInt(); String[] id=new String[n]; for(int i=0;i<n;i++) { int l=0; id[i]=s.next(); int c=1,c1=0; for(int k=c1;k<c;k++) { String b=id[k].toLowerCase(); boolean l1=holly(b); if(id[k]==b) { System.out.println(b); } }c1++; int x = 0; int count=0,count1=0; char[] a=id[i].toCharArray(); int g=0; for(int j=0;j<a.length;j++) { if(Character.isLetterOrDigit(a[j])) { } else { if(a[j]=='@') { count++; } else { if(Character.isLetterOrDigit(a[j+1])) { } else throw new test(); if(count==1) { if(a[j]=='.') { l++; } } boolean z=try1(a[j]); if(z==true) { } else g=1; } } } if(g==1) { throw new test(); } if(count==0) { throw new test(); } else if(count==2) { throw new test(); } if(l==0) { throw new test(); } c++; } } catch(test ex) { System.out.println("enter the id is not correct"); } } } 

I have made a class earlier for an Android Application you might find it useful

 package com.amit.parking.parking.Analytics; import android.widget.EditText; import java.util.ArrayList; /** * Created by Android Developer on 3/1/2015. */ public class EmailValidator { private static String email; private static int count = 0; private static final Character [] alphabeticSmall = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; private static final Character [] alphabeticLarge = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; private static final Character [] forbiddenSymbols = { '\'','^','[',',','!','#','$','%','&','*','+','/','=', '?','`','{','|','}','~',']','(',')',':','\\',' ','÷' ,'×','؛','<','>','|',';','"','₩','¥','£','€','`','°' ,'•','○','●','□','■','♤','♡','♢','♧','☆','¤','《', '》','¡','¿' }; private String[] validEnds = {"ac", "ad", "ae", "aero", "af", "ag", "ai", "al", "am", "an", "ao", "aq", "ar", "arpa", "as", "asia", "at", "au", "aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz", "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca", "cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co", "com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk", "dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi", "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw", "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in", "info", "int", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jobs", "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma", "mc", "md", "me", "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo", "mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx", "my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni", "nl", "no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph", "pk", "pl", "pm", "pn", "pr", "pro", "ps", "pt", "pw", "py", "qa", "re", "ro", "rs", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si", "sj", "sk", "sl", "sm", "sn", "so", "sr", "st", "su", "sv", "sy", "sz", "tc", "td", "tel", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to", "tp", "tr", "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um", "us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws", "ye", "yt", "yu", "za", "zm", "zw"}; private static ArrayList<Character> correctSmallLetters; private static ArrayList<Character> correctLargeLetters; private static ArrayList<Character> forbiddenSymbolsArray; private static CharSequence cleanText = ""; private static CharSequence [] cleanTextToArray; private static int dynamicArraySize = 1; private static Character [] dynamicArray; public EmailValidator(String email){ this.email = email; correctSmallLetters = new ArrayList<>(); correctLargeLetters = new ArrayList<>(); forbiddenSymbolsArray = new ArrayList<>(); } public static boolean isEmailCharactersValidated(){ if(equalsGetSmallLetters() || equalsGetLargeLetters()){ return true; } return false; } private static boolean equalsGetSmallLetters() { count = 0; while(count < email.length()) { for (int smallLetterIndex = 0; smallLetterIndex < alphabeticSmall.length; smallLetterIndex++) { if(email.charAt(count) == alphabeticSmall[smallLetterIndex]){ correctSmallLetters.add(email.charAt(count)); } } count++; } count = 0; return correctSmallLetters.size() > 0; } private static boolean equalsGetLargeLetters() { count = 0; while(count < email.length()) { for (int largeLetterIndex = 0; largeLetterIndex < alphabeticLarge.length; largeLetterIndex++) { if(email.charAt(count) == alphabeticLarge[largeLetterIndex]){ correctLargeLetters.add(email.charAt(count)); } } count++; } count = 0; return correctLargeLetters.size() > 0; } public static boolean isEmailHasForbiddenSymbols(){ count = 0; while(count < email.length()) { for (int symbolIndex = 0; symbolIndex < forbiddenSymbols.length; symbolIndex++) { if(email.charAt(count) == forbiddenSymbols[symbolIndex]){ forbiddenSymbolsArray.add(email.charAt(count)); //addToTheDynamicArray(email.charAt(count)); } } count++; } count = 0; return forbiddenSymbolsArray.size() > 0; } /* THIS IS JUST A TEST METHOD... */ private static void addToTheDynamicArray(Character c){ dynamicArray = new Character[dynamicArraySize]; if (dynamicArray.length == 1) { dynamicArray[dynamicArraySize -1] = c; dynamicArraySize++; } else { dynamicArray = new Character[dynamicArraySize]; dynamicArray[dynamicArraySize -1] = c; dynamicArraySize++; } } public static void removeForbiddenSymbols(EditText etEmail){ try { count = 0; while (count < etEmail.getText().toString().length()) { for (int symbolIndex = 0; symbolIndex < forbiddenSymbols.length; symbolIndex++) { if (etEmail.getText().toString().charAt(count) == forbiddenSymbols[symbolIndex]) { etEmail.setText(etEmail.getText().toString().replace(String.valueOf(etEmail.getText().toString().charAt(count)), "")); } } count++; } count = 0; }catch (Exception ignored) { } } public boolean isEmailCorrect() {return checkForAts() && checkForDots();} private boolean checkForAts() { int atsCount = 0; ArrayList<Character> ats = new ArrayList<>(); while(atsCount < email.length()){ if(email.charAt(atsCount) == '@'){ ats.add(email.charAt(atsCount)); } atsCount++; } return ats.size() == 1; } public boolean isEmailHasValidEnd(){ int validEndsCount = 0; int emailCharsCount = 0; while (emailCharsCount < email.length()){ while(validEndsCount < validEnds.length){ if(email.endsWith(validEnds[validEndsCount])) return true; validEndsCount++; } emailCharsCount++; } return false; } private boolean checkForDots() { int dotsCount = 0; ArrayList<Character> dots = new ArrayList<>(); while(dotsCount < email.length()){ if(email.charAt(dotsCount) == '.'){ dots.add(email.charAt(dotsCount)); } dotsCount++; } return dots.size() == 1; } public boolean isValidEmailAddress(String email) { String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$"; java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern); java.util.regex.Matcher m = p.matcher(email); return m.matches(); } 

}