validator validate pattern framework for emailvalidator commons validation email apache-commons java

validation - validate - ¿Cuál es el mejor método de validación de direcciones de correo electrónico de Java?



string pattern for email (19)

¿Qué quieres validar? ¿La direccion de correo electronico?

La dirección de correo electrónico solo puede ser verificada para su conformidad de formato Consulte el estándar: RFC2822 . La mejor manera de hacerlo es una expresión regular. Nunca sabrás si realmente existe sin enviar un correo electrónico.

Revisé el validador común. Contiene una clase org.apache.commons.validator.EmailValidator. Parece ser un buen punto de partida.

¿Cuáles son las buenas bibliotecas de validación de direcciones de correo electrónico para Java? ¿Hay alguna alternativa al validador de los bienes comunes ?


Apache Commons es generalmente conocido como un proyecto sólido. Sin embargo, tenga en cuenta que todavía tendrá que enviar un correo electrónico de verificación a la dirección si desea asegurarse de que sea un correo electrónico real y que el propietario quiera que se use en su sitio.

EDITAR : Hubo un bug en el que era demasiado restrictivo en el dominio, por lo que no aceptaba correos electrónicos válidos de nuevos TLD.

Este error se resolvió el 03 / Jan / 15 02:48 en commons-validator versión 1.4.1


El validador de Apache Commons se puede usar como se menciona en las otras respuestas.

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''

La importación:

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

El código:

String email = "[email protected]"; boolean valid = EmailValidator.getInstance().isValid(email);

y permitir direcciones locales

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


La versión actual de Apache Commons Validator es 1.3.1 .

La clase que valida es org.apache.commons.validator.EmailValidator. Tiene una importación para org.apache.oro.text.perl.Perl5Util que es de un proyecto retirado Jakarta ORO .

Por cierto, encontré que hay una versión 1.4, aquí están los documentos API . En el site dice: "Última publicación: 05 de marzo de 2008 | Versión: 1.4-SNAPSHOT", pero eso no es definitivo. Única forma de construirse (pero esto es una instantánea, no LIBERACIÓN) y usar o descargar desde here . Esto significa que 1.4 no se ha hecho definitivo durante tres años (2008-2011). Esto no está en el estilo de Apache. Estoy buscando una mejor opción, pero no encontré una que sea muy adoptada. Quiero usar algo que esté bien probado, no quiero atacar ningún error.


Les Hazlewood ha escrito una clase de validador de correo electrónico compatible con RFC 2822 muy completa utilizando expresiones regulares de Java. Lo puedes encontrar en http://www.leshazlewood.com/?p=23 . Sin embargo, su minuciosidad (o la implementación de Java RE) lleva a la ineficiencia: lea los comentarios sobre los tiempos de análisis para las direcciones largas.


Me pregunto por qué a nadie se le ocurrió el @Email de las restricciones adicionales de Hibernate Validator. El validador en sí es EmailValidator .


Porté parte del código en 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(); } }

Con un validador de nombre de host de la siguiente manera:

@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("网络", 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("网络")) { // 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()]); } }

Y un validIDNs.xml con patrones de expresiones regulares para los diferentes tlds (demasiado grande para incluir :)

<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>


Respuesta tardía, pero creo que es simple y digna:

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(); }

Casos de prueba :

Para fines de producción, las validaciones de nombres de dominio deben realizarse en red.


Si bien existen muchas alternativas a los bienes comunes de Apache, sus implementaciones son rudimentarias en el mejor de los casos (como la implementación de los bienes comunes de Apache ) e incluso están totalmente equivocadas en otros casos.

También me mantendría alejado de las llamadas expresiones regulares "no restrictivas" simples; No hay tal cosa. Por ejemplo, @ se permite varias veces según el contexto, ¿cómo sabe si se necesita el requerido? Simple regex no lo entenderá, a pesar de que el correo electrónico debe ser válido. Cualquier cosa más compleja se vuelve error-prone o incluso contiene asesinos de rendimiento ocultos . ¿Cómo vas a mantener algo como this ?

El único validador completo basado email-rfc2822-validator regulares compatible con RFC que conozco es email-rfc2822-validator con su expresión regular "refinada" apropiadamente llamada Dragons.java . Sin embargo, solo es compatible con la especificación RFC-2822 , aunque es lo suficientemente adecuada para las necesidades modernas (RFC-5322 la updates en áreas que ya están fuera del alcance de los casos de uso diario).

Pero lo que realmente desea es un lexer que analice correctamente una cadena y la divida en la estructura de componentes de acuerdo con la gramática RFC. EmailValidator4J parece prometedor a ese respecto, pero aún es joven y limitado.

Otra opción que tiene es usar un servicio web como el servicio web de validación de batalla de Mailgun o la API de Mailboxlayer (solo tomó los primeros resultados de Google). No es estrictamente compatible con RFC, pero funciona lo suficientemente bien para las necesidades modernas.


Si desea verificar si una dirección de correo electrónico es válida, entonces VRFY le proporcionará parte del camino. He encontrado que es útil para validar direcciones de intranet (es decir, direcciones de correo electrónico para sitios internos). Sin embargo, es menos útil para los servidores de correo de Internet (vea las advertencias en la parte superior de esta página)


Si está intentando realizar una validación de formulario recibida del cliente, o simplemente una validación de bean, hágalo simple. Es mejor hacer una validación de correo electrónico suelta en lugar de hacer una estricta y rechazar a algunas personas (por ejemplo, cuando intentan registrarse para su servicio web). Con casi cualquier cosa permitida en la parte del nombre de usuario del correo electrónico y tantos nuevos dominios agregados literalmente cada mes (por ejemplo, .company, .entreprise, .estate), es más seguro no ser restrictivo:

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


Tarde a la pregunta, aquí, pero: mantengo una clase en esta dirección: http://lacinato.com/cm/software/emailrelated/emailaddress

Se basa en la clase de Les Hazlewood, pero tiene numerosas mejoras y corrige algunos errores. Licencia de apache.

Creo que es el analizador de correo electrónico más capaz de Java, y todavía tengo que ver uno más capaz en cualquier idioma, aunque puede haber uno por ahí. No es un analizador de estilo lexer, pero utiliza algunas expresiones regulares de Java complicadas, y por lo tanto no es tan eficiente como podría ser, pero mi compañía ha analizado más de 10 mil millones de direcciones reales con él: ciertamente es utilizable en un alto rendimiento. situación. Tal vez una vez al año llegue a una dirección que provoque un desbordamiento de la pila de expresiones regulares (de manera apropiada), pero estas son direcciones de correo no deseado que tienen cientos o miles de caracteres, con muchas comillas, paréntesis y similares.

RFC 2822 y las especificaciones relacionadas son realmente bastante permisivas en términos de direcciones de correo electrónico, por lo que una clase como esta es una exageración para la mayoría de los usos. Por ejemplo, la siguiente es una dirección legítima, según especificaciones, espacios y todos:

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

Ningún servidor de correo lo permitiría, pero esta clase puede analizarlo (y reescribirlo en un formulario utilizable).

Descubrimos que las opciones existentes del analizador de correo electrónico de Java no son lo suficientemente duraderas (es decir, todas ellas no pudieron analizar algunas direcciones válidas), por lo que creamos esta clase.

El código está bien documentado y tiene muchas opciones fáciles de cambiar para permitir o rechazar ciertos formularios de correo electrónico. También proporciona muchos métodos para acceder a ciertas partes de la dirección (lado izquierdo, lado derecho, nombres personales, comentarios, etc.), para analizar / validar los encabezados de la lista de buzones, para analizar / validar la ruta de retorno (que es único entre los encabezados), y así sucesivamente.

El código como está escrito tiene una dependencia javamail, pero es fácil de eliminar si no quieres la funcionalidad menor que proporciona.


Usar el paquete de correo electrónico oficial de Java es lo más fácil:

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


Este es el mejor método:

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())); }

Fuentes: - howtodoinjava.com/2014/11/11/java-regex-validate-email-address

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


Aquí está mi enfoque pragmático, donde solo quiero direcciones blah @ de dominio razonablemente diferenciadas utilizando los caracteres permitidos de la RFC. Las direcciones se deben convertir a minúsculas de antemano.

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(); } }


Otra opción es usar el validador de correo electrónico de Hibernate , usar la anotación @Emailo usar la clase del validador programáticamente, como:

import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator; class Validator { // code private boolean isValidEmail(String email) { EmailValidator emailValidator = new EmailValidator(); return emailValidator.isValid(email, null); } }


Parece que no hay bibliotecas perfectas o formas de hacerlo usted mismo, a menos que tenga tiempo para enviar un correo electrónico a la dirección de correo electrónico y esperar una respuesta (aunque esta no sea una opción). Terminé usando una sugerencia de aquí http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/ y ajustando el código para que funcione en 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(); }


También es posible que desee verificar la longitud: los correos electrónicos tienen una longitud máxima de 254 caracteres. Utilizo el validador de apache commons y no se comprueba esto.


public class Validations { private Pattern regexPattern; private Matcher regMatcher; public String validateEmailAddress(String emailAddress) { regexPattern = Pattern.compile("^[(a-zA-Z-0-9-//_//+//.)]+@[(a-z-A-z)]+//.[(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 = "[email protected]"; String mobileNumber = "+91-9986571622"; Validations validations = new Validations(); System.out.println(validations.validateEmailAddress(emailAddress)); System.out.println(validations.validateMobileNumber(mobileNumber)); } }