Каков наилучший метод проверки адреса электронной почты Java?

Каковы хорошие библиотеки проверки адресов электронной почты для Java? Существуют ли альтернативы валидатору общих ресурсов?

Ответ 1

Apache Commons обычно известен как солидный проект. Однако имейте в виду, что вам все равно придется отправить электронное письмо с подтверждением на адрес, если вы хотите убедиться, что это настоящий адрес электронной почты и что владелец хочет, чтобы он использовался на вашем сайте.

EDIT. Была ошибка где она была слишком ограничительной для домена, в результате чего она не принимала действительные электронные письма из новых TLD.

Эта ошибка была решена в 03/янв./15 02:48 в общедоступной версии версии 1.4.1

Ответ 2

Использование официального официального пакета электронной почты 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;
}

Ответ 3

Валидатор Apache Commons может использоваться, как указано в других ответах.

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 org.apache.commons.validator.routines.EmailValidator;

Код:

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

и разрешить локальные адреса

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

Ответ 4

Поздний ответ, но я думаю, что это просто и достойно:

    public boolean isValidEmailAddress(String email) {
           String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected]((\\[[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();
    }

Тестовые случаи:

enter image description here

Для производственных целей проверки имени домена должны выполняться по сети.

Ответ 5

Если вы пытаетесь выполнить валидацию формы, полученную от клиента, или только проверку валидации bean, сохраните ее просто. Лучше выполнять свободную проверку подлинности электронной почты, а не выполнять строгую проверку и отвергать некоторых людей (например, когда они пытаются зарегистрироваться для вашего веб-сервиса). Почти все, что разрешено в части имени пользователя электронной почты и так много новых доменов, добавляемых буквально каждый месяц (например .company,.entreprise,.estate), безопаснее не ограничивать:

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

Ответ 6

Позднее к вопросу, здесь, но: я поддерживаю класс по этому адресу: http://lacinato.com/cm/software/emailrelated/emailaddress

Он основан на классе Les Hazlewood, но имеет множество улучшений и исправляет несколько ошибок. Лицензия Apache.

Я считаю, что это самый эффективный парсер для электронной почты на Java, и мне еще предстоит увидеть еще один способный на любом языке, хотя там может быть один. Это не лексерский синтаксический анализатор, но использует некоторое сложное java-регулярное выражение и, следовательно, не так эффективно, как могло бы быть, но моя компания проанализировала более 10 миллиардов адресов в реальном мире: он, безусловно, можно использовать в высокопроизводительных ситуация. Возможно, раз в год он попадает в адрес, который вызывает переполнение стека регулярных выражений (соответственно), но это адреса спама, длина которых составляет сотни или тысячи символов с большим количеством котировок и скобок и т.п.

RFC 2822, и соответствующие спецификации действительно весьма разрешительны с точки зрения адресов электронной почты, поэтому класс, подобный этому, является излишним для большинства целей. Например, следующий законный адрес, согласно спецификации, пробелам и всем:

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

Никакой почтовый сервер не допускает этого, но этот класс может его проанализировать (и переписать его в полезную форму).

Мы обнаружили, что существующие параметры парсера Java для электронной почты недостаточно долговечны (что означает, что все они не могут анализировать некоторые действительные адреса), поэтому мы создали этот класс.

Код хорошо документирован и содержит множество простых для изменения параметров, позволяющих или запрещающих определенные формы электронной почты. Он также предоставляет множество способов доступа к определенным частям адреса (левая сторона, правая сторона, личные имена, комментарии и т.д.), Для анализа/проверки заголовков списка почтовых ящиков, для синтаксического анализа/проверки пути возврата (что является уникальным среди заголовков) и т.д.

В написанном коде есть javamail-зависимость, но его легко удалить, если вы не хотите, чтобы предоставляемые им незначительные функции.

Ответ 7

Мне просто интересно, почему никто не придумал @Email дополнительные ограничения Hibernate Validator. Сам валидатор EmailValidator.

Ответ 8

Les Hazlewood написал очень тщательный RFAC 2822 совместимый класс проверки подлинности электронной почты с использованием регулярных выражений Java. Вы можете найти его на http://www.leshazlewood.com/?p=23. Однако его тщательность (или реализация Java RE) приводит к неэффективности - читайте комментарии о времени разбора для длинных адресов.

Ответ 9

Я портировал часть кода в 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();
    }
}

С помощью валидатора имени хоста:

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

И validIDNs.xml с шаблонами регулярных выражений для разных tld (слишком большой для включения:)

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

Ответ 10

public class Validations {

    private Pattern regexPattern;
    private Matcher regMatcher;

    public String validateEmailAddress(String emailAddress) {

        regexPattern = Pattern.compile("^[(a-zA-Z-0-9-\\_\\+\\.)][email protected][(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));
    }
}

Ответ 11

Если вы хотите проверить, действительно ли адрес электронной почты, то VRFY поможет вам в этом. Я нашел его полезным для проверки адресов интрасети (то есть адресов электронной почты для внутренних сайтов). Однако это менее полезно для интернет-почтовых серверов (см. Оговорки в верхней части этой страницы).

Ответ 12

Несмотря на то, что существует много альтернатив Apache Commons, их реализации в лучшем случае рудиментарны (как и сама реализация Apache Commons) и даже совершенно неверны в других случаях.

Я бы также держался подальше от так называемого простого "неограничительного" регулярного выражения; нет такой вещи Например, @допускается несколько раз в зависимости от контекста. Откуда вы знаете, что требуемый есть? Простое регулярное выражение не поймет этого, хотя электронная почта должна быть действительной. Все более сложное становится подверженным ошибкам или даже содержит скрытые убийства производительности. Как вы собираетесь поддерживать что - то вроде этого?

Единственный известный мне валидатор на основе регулярных выражений, совместимый с RFC, - это email-rfc2822-validator с его уточненным регулярным выражением, соответствующим образом названным Dragons.java. Он поддерживает только более старую спецификацию RFC-2822, хотя и достаточно подходит для современных нужд (RFC-5322 обновляет ее в областях, которые уже выходят за рамки ежедневного использования).

Но на самом деле вам нужен лексер, который правильно анализирует строку и разбивает ее на структуру компонентов в соответствии с грамматикой RFC. EmailValidator4J кажется многообещающим в этом отношении, но все еще молод и ограничен.

Другой вариант, который у вас есть, - это использование веб-службы, такой как проверенная в бою веб-служба проверки Mailgun или API Mailboxlayer (только что были получены первые результаты Google). Он не является строго RFC-совместимым, но работает достаточно хорошо для современных нужд.

Ответ 13

Что вы хотите проверить? Адрес электронной почты?

Адрес электронной почты может быть проверен только для соответствия формата. См. Стандарт: RFC2822. Лучший способ сделать это - регулярное выражение. Вы никогда не узнаете, действительно ли существует, не отправив электронное письмо.

Я проверил валидатор общедоступности. Он содержит класс org.apache.commons.validator.EmailValidator. Кажется хорошей отправной точкой.

Ответ 14

Текущая версия Validator Apocal Commons 1.3.1.

Класс, который проверяет, - org.apache.commons.validator.EmailValidator. У него есть импорт для org.apache.oro.text.perl.Perl5Util, который находится в отставке Проект Джакарта ORO.

Кстати, я обнаружил, что существует версия 1.4, вот документы API. На сайте он говорит: "Последнее опубликовано: 05 марта 2008 г. Версия: 1.4-SNAPSHOT" , но это не окончательно. Только способ создать себя (но это снимок, а не RELEASE) и использовать или загрузить с здесь. Это означает, что 1.4 не был окончательным в течение трех лет (2008-2011 гг.). Это не в стиле Apache. Я ищу лучший вариант, но не нашел тот, который очень усыновлен. Я хочу использовать что-то хорошо протестированное, не хочу ударять об ошибках.

Ответ 15

Вы также можете проверить длину - электронные письма не более 254 символов. Я использую валидатор apache commons, и он не проверяет это.

Ответ 16

| * | Простой Проверьте правильность электронной почты:

static boolean isValidEmailAddress(String emailVar)
{
    String mylRegExpVar = "[A-Za-z0-9._%+-]{2,}[email protected][A-Za-z-]{2,}+\\.[A-Za-z]{2,}";

    Pattern pVar = Pattern.compile(mylRegExpVar);
    Matcher mVar = pVar.matcher(emailVar);
    return mVar.matches();
}

Ответ 17

Я использую regex для этого:

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

Ответ 18

Абсолютный валидатор

Я назвал это так, потому что я думаю, что ничто не может его сломать и оно принимает любой домен, если он действителен

public boolean isEmail(String email) {
    //Checks of all possible gaps
    if (email.matches("(?:[a-zA-Z0-9]+(?:\\.[a-zA-Z0-9]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])")) {
        //Then checks if email address contains at least 1 alphabet in each separation
        if (email.matches(".*([a-zA-Z]).*@.*.([a-z])")) {
            // If you would do, Put here your fake-emails-checker 
            return true;
        } else {
            return false;
        }
    }
    return false;
}

Не будет принято

test [email protected]
[email protected]
[email protected]@gmail.com
test%[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected] //No alphabet at the end, It sounds like IP

Он не примет никаких символических символов, таких как ($, *, π,! и т.д.)

ПРИНЯТ

[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]rg
[email protected]

Этот валидатор принимает символы нижнего и верхнего регистра, которые до @

Если вы хотите принять только только в нижнем регистре
затем просто удалите A-Z из выражений регулярных выражений

И наоборот, однако Адреса электронной почты не зависят от случая

Это просто проверка E-mail formatting, поэтому, если вы управляете системой учетных записей Вы должны отправить Проверка электронной почты после проверки. Также попробуйте предотвратить поддельные электронные письма через for-loop со списком Domains , который вы не хотите

String[] email_domain = email.split("@");

и начать проверку/цикл с помощью email_domain[1] Строка
с list Массивом строк DOMAINS

Тест для Android

if(!isEmail(emailField.getText().toString())){
    Snackbar.make(v,
            "This does not seem like an valid E-mail!",
            Snackbar.LENGTH_LONG).show();
}

Ответ 19

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

        }
    }
}

Ответ 20

Это самый простой способ сделать это без каких-либо регулярных выражений или Object-Armageddon.

"[email protected]" = 0

"[email protected]" = 0 vorlaufende und nachlaufende Leerzeichen werden unterdrueckt

"[email protected]" = 0 Zeichen "_" und "-" duerfen vorkommen

"[email protected]" = 0 минимальный gueltige Laenge sind 6 Zeichen

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

". [email protected]" = 5 Начать auf.

"[email protected]" = 16 Ende auf.

"ABCDEF @GHIJKL" = 13 Keinen Punkt gefunden

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

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

"[email protected]" = 3 Zahl nach dem AT-Zeichen

"[email protected]_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

"[email protected]" = 17 Верхний уровень 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 "[email protected]"

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

Ответ 21

Кажется, нет идеальных библиотек или способов сделать это самостоятельно, если только вам не пришло время отправить электронное письмо на адрес электронной почты и ждать ответа (возможно, это не вариант). Я закончил тем, что предложил здесь 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._%+-][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    String laxString = "[email protected]+\\.[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();
}

Ответ 22

Это лучший способ:

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

Ответ 23

Другой вариант - использовать валидатор электронной почты Hibernate, используя аннотацию @Email или программно используя класс валидатора, например:

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

}

Ответ 24

Вот мой прагматичный подход, где мне просто нужны разумные отдельные адреса доменов blah @с использованием допустимых символов из RFC. Адреса должны быть предварительно преобразованы в нижний регистр.

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

}

Ответ 25

/* для проверки идентификатора электронной почты без использования регулярных выражений и пакетов а затем ваш символ подтверждения и расширения домена, которые вы можете добавить... ниже try1, методы holly */

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

Ответ 26

Я сделал класс раньше для Android-приложения, которое может показаться вам полезным

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.!#$%&'*+/=?^_`{|}~-][email protected]((\\[[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();
}

}