Wat is de beste validatiemethode voor Java-e-mailadressen?

Wat zijn de goede bibliotheken voor het valideren van e-mailadressen voor Java? Zijn er alternatieven voor commons validator?


Antwoord 1, autoriteit 100%

Apache Commons staat algemeen bekend als een solide project. Houd er echter rekening mee dat u nog steeds een verificatie-e-mail naar het adres moet sturen als u zeker wilt weten dat het een echte e-mail is en dat de eigenaar wil dat deze op uw site wordt gebruikt.

EDIT: er was een bugwaarbij het was te beperkend voor het domein, waardoor het geen geldige e-mails van nieuwe TLD’s accepteerde.

Deze bug is opgelost op 03/Jan/15 02:48 in commons-validatorversie 1.4.1


Antwoord 2, autoriteit 93%

Het officiële java e-mailpakketgebruiken is het gemakkelijkst:

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

Antwoord 3, autoriteit 68%

Apache Commons-validator kan worden gebruikt zoals vermeld in de andere antwoorden.

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'

De import:

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

De code:

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

en om lokale adressen toe te staan

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

Antwoord 4, autoriteit 53%

Laat antwoord, maar ik denk dat het eenvoudig en waardig is:

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

Testgevallen:

Voor productiedoeleinden moeten Domeinnaamvalidaties netwerkgewijs worden uitgevoerd.


Antwoord 5, autoriteit 16%

Als je een formuliervalidatie probeert uit te voeren die is ontvangen van de client, of gewoon een bean-validatie, houd het dan simpel.
Het is beter om een losse e-mailvalidatie te doen in plaats van een strikte te doen en sommige mensen af te wijzen (bijvoorbeeld wanneer ze zich proberen te registreren voor uw webservice).
Met bijna alles dat is toegestaan in het gebruikersnaamgedeelte van de e-mail en zoveel nieuwe domeinen die letterlijk elke maand worden toegevoegd (bijvoorbeeld .company, .entreprise, .estate), is het veiliger om niet beperkend te zijn:

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

Antwoord 6, autoriteit 5%

Laat met de vraag, hier, maar: ik onderhoud een les op dit adres: http:/ /lacinato.com/cm/software/emailrelated/emailadres

Het is gebaseerd op de klasse van Les Hazlewood, maar heeft talloze verbeteringen en lost een paar bugs op. Apache-licentie.

Ik geloof dat het de meest capabele e-mailparser in Java is, en ik heb er nog niet een gezien die meer in staat is in welke taal dan ook, hoewel er misschien een is. Het is geen lexer-achtige parser, maar gebruikt een ingewikkelde java-regex, en is dus niet zo efficiënt als het zou kunnen zijn, maar mijn bedrijf heeft er meer dan 10 miljard echte adressen mee geparseerd: het is zeker bruikbaar in een krachtige situatie. Misschien zal het één keer per jaar een adres raken dat (gepast) een regex-stack overflow veroorzaakt, maar dit zijn spam-adressen die honderden of duizenden tekens lang zijn met veel aanhalingstekens en haakjes en dergelijke.

RFC 2822en de bijbehorende specificaties zijn echt vrij tolerant in termen van e-mailadressen, dus een klasse als deze is overkill voor de meeste toepassingen. Het volgende is bijvoorbeeld een legitiem adres, volgens de specificaties, spaties en alles:

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

Geen enkele mailserver zou dat toestaan, maar deze klasse kan het ontleden (en herschrijven naar een bruikbare vorm).

We vonden dat de bestaande Java-e-mailparseropties onvoldoende duurzaam waren (wat betekent dat ze niet allemaal enkele geldige adressen konden ontleden), dus hebben we deze klasse gemaakt.

De code is goed gedocumenteerd en heeft veel gemakkelijk te wijzigen opties om bepaalde e-mailformulieren toe te staan of niet toe te staan. Het biedt ook veel methoden om toegang te krijgen tot bepaalde delen van het adres (linkerkant, rechterkant, persoonlijke namen, opmerkingen, enz.), Om mailboxlijstkoppen te ontleden/valideren, om het retourpad te ontleden/valideren (wat uniek is onder de koppen), enzovoort.

De code zoals geschreven is afhankelijk van javamail, maar is gemakkelijk te verwijderen als u de kleine functionaliteit die deze biedt niet wilt.


Antwoord 7, autoriteit 5%

Ik vraag me af waarom niemand @Emailvan de aanvullende beperkingen van Hibernate Validator. De validator zelf is EmailValidator.


Antwoord 8, autoriteit 4%

Les Hazlewood heeft een zeer grondige RFC 2822-compatibele e-mailvalidatieklasse geschreven met behulp van Java-reguliere expressies. Je kunt het vinden op http://www.leshazlewood.com/?p=23. De grondigheid (of de Java RE-implementatie) leidt echter tot inefficiëntie – lees de opmerkingen over het parseren van tijden voor lange adressen.


Antwoord 9, autoriteit 2%

Ik heb een deel van de code geporteerd in 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();
    }
}

Met een hostnaamvalidator als volgt:

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

En een validIDNs.xml met reguliere expressie patronen voor de verschillende TLD’s (te groot om onder meer:)

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

Antwoord 10, Autoriteit 2%

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

Antwoord 11

Als je wilt controleren of een e-mailadres geldig is, gebruik dan VRFYje een eindje op weg helpen. Ik heb gemerkt dat het nuttig is voor het valideren van intranet-adressen (dat wil zeggen, e-mailadressen voor interne sites). Het is echter minder handig voor internetmailservers (zie de waarschuwingen bovenaan deze pagina)


Antwoord 12

Hoewel er veel alternatieven zijn voor Apache commons, zijn hun implementaties op zijn best rudimentair (zoals Apache commons’implementatiezelf) en in andere gevallen zelfs helemaal verkeerd.

Ik zou ook wegblijven van de zogenaamde eenvoudige ‘niet-beperkende’ regex; zoiets bestaat niet. Bijvoorbeeld @ is meerdere keren toegestaanafhankelijk van de context , hoe weet je dat de vereiste er is? Eenvoudige regex zal het niet begrijpen, ook al zou de e-mail geldig moeten zijn. Alles wat complexerwordt foutgevoeligof zelfs verborgen prestatiemoordenaars. Hoe ga je zoiets als dit?

De enige uitgebreide RFC-compatibele regex-gebaseerde validator die ik ken, is email-rfc2822-validator met zijn ‘verfijnde’ regex met de toepasselijke naam Dragons.java. Het ondersteunt echter alleen de oudere RFC-2822-specificatie, hoewel geschikt genoeg voor moderne behoeften (RFC- 5322 updatesin gebieden die al buiten het bereik vallen voor dagelijks gebruik).

Maar echt wat je wiltis een lexerdie een string correct ontleedt en opdeelt in de componentenstructuur volgens de RFC-grammatica. EmailValidator4Jlijkt in dat opzicht veelbelovend, maar is nog jong en beperkt.

Een andere optie die je hebt is het gebruik van een webservice zoals de door Mailgun geteste validatiewebserviceof Mailboxlayer API(heeft zojuist de eerste Google-resultaten genomen). Het is niet strikt RFC-compatibel, maar werkt goed genoeg voor moderne behoeften.


Antwoord 13

Wat wil je valideren? Het e-mailadres?

Het e-mailadres kan alleen worden gecontroleerd op conformiteit met het formaat. Zie de standaard: RFC2822. De beste manier om dat te doen is een reguliere expressie. Je zult nooit weten of het echt bestaat zonder een e-mail te sturen.

Ik heb de commons-validator gecontroleerd. Het bevat een klasse org.apache.commons.validator.EmailValidator. Lijkt een goed startpunt te zijn.


Antwoord 14

De huidige Apache Commons Validator-versie is 1.3.1.

Klasse die valideert is org.apache.commons.validator.EmailValidator. Het heeft een import voor org.apache.oro.text.perl. Perl5Utilvan een gepensioneerd Jakarta ORO-project.

BTW, ik vond dat er een 1.4-versie is, Hier zijn de API-documenten . Op de site het zegt: “Laatst gepubliceerd: 05 maart 2008 | Versie: 1.4-Snapshot”, maar dat is geen finale. Alleen manier om jezelf te bouwen (maar dit is een momentopname, niet vrijgeven) en gebruik of downloaden van hier . Dit betekent 1.4 is gedurende drie jaar geen definitief (2008-2011) gemaakt. Dit is niet in de stijl van Apache.
Ik ben op zoek naar een betere optie, maar vond er geen die erg is geadopteerd. Ik wil iets gebruiken dat goed is getest, wil geen beestjes raken.


Antwoord 15

Mogelijk wilt u controleren op de lengte – e-mails zijn maximaal 254 tekens lang. Ik gebruik de Apache Commons-validator en het controleert dit niet.


Antwoord 16

Er lijkt geen perfecte bibliotheken of manieren te zijn om dit zelf te doen, tenzij je tijd hebt om een ​​e-mail te sturen naar het e-mailadres en op een reactie te wachten (dit is echter misschien geen optie). Ik eindigde met een suggestie van hier http: // blog.logichigh.com/2010/09/02/validating-an-e-mail-address/ en het aanpassen van de code, zodat deze in Java zou werken.

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

Antwoord 17

Dit is de beste methode:

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

BRONNEN: –
http://howtodoinjava.com/2014/11/11/ Java-Regex-validate-e-mailadres /

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


Antwoord 18

Een andere optie is gebruik van de Hibernate e-mailvalidator , met behulp van de annotatie @Emailof gebruikmakend van de validatorklasse programmatisch, zoals:

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

Antwoord 19

Hier is mijn pragmatische aanpak, waar ik gewoon redelijke onderscheiden blah @ domeinadressen wil met behulp van de toegestane tekens van de RFC. Adressen moeten vooraf worden geconverteerd naar kleine letters.

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

Other episodes