ما هي أفضل طريقة للتحقق من صحة عنوان البريد الإلكتروني في Java؟[مغلق]

StackOverflow https://stackoverflow.com/questions/624581

سؤال

ما هي مكتبات التحقق من صحة عنوان البريد الإلكتروني الجيدة لجافا؟هل هناك أي بدائل ل المدقق المشترك?

هل كانت مفيدة؟

المحلول

يُعرف Apache Commons عمومًا بأنه مشروع قوي.ومع ذلك، ضع في اعتبارك أنه لا يزال يتعين عليك إرسال بريد إلكتروني للتحقق إلى العنوان إذا كنت تريد التأكد من أنه بريد إلكتروني حقيقي، وأن المالك يريد استخدامه على موقعك.

يحرر:كان هناك حشرة حيث كان مقيدًا للغاية على النطاق، مما أدى إلى عدم قبول رسائل البريد الإلكتروني الصالحة من نطاقات TLD الجديدة.

تم حل هذا الخطأ في 03/يناير/15 الساعة 02:48 مساءً المدقق المشترك الإصدار 1.4.1

نصائح أخرى

واستخدام جافا حزمة البريد الإلكتروني مسؤول هو أسهل:

public static boolean isValidEmailAddress(String email) {
   boolean result = true;
   try {
      InternetAddress emailAddr = new InternetAddress(email);
      emailAddr.validate();
   } catch (AddressException ex) {
      result = false;
   }
   return result;
}
ويمكن استخدام

وأباتشي العموم المصادقة على النحو المذكور في إجابات أخرى.

و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 = "myName@example.com";
boolean valid = EmailValidator.getInstance().isValid(email);

ووالسماح للعناوين المحلية

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

والجواب في وقت متأخر، ولكن أعتقد أنها بسيطة وتستحق:

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

<قوية> حالات الاختبار : ل

لغرض الإنتاج، ويجب أن يتم تنفيذ التحقق من صحة اسم المجال شبكة الحكيم.

إذا كنت تحاول القيام التحقق من صحة النموذج الواردة من العميل، أو مجرد التحقق من صحة الفول - يبقيه بسيط. فمن الأفضل أن تفعل التحقق من صحة البريد الإلكتروني فضفاضة بدلا من القيام واحد صارم ورفض بعض الناس، (على سبيل المثال، عندما تحاول تسجيل لخدمة الويب الخاص بك). مع أي شيء تقريبا المسموح بها في الجزء المستخدم من البريد الإلكتروني والعديد من المجالات الجديدة التي تضاف حرفيا كل شهر (على سبيل المثال. الشركة، .entreprise، .estate)، انها أكثر أمانا لا تكون مقيدة:

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

وفي وقت متأخر على السؤال، هنا، ولكن: أنا الحفاظ على الطبقة على هذا العنوان: HTTP: / /lacinato.com/cm/software/emailrelated/emailaddress

ولأنه يقوم على الدرجة ليه HAZLEWOOD، ولكن لديها العديد من التحسينات وإصلاح عدد قليل من البق. أباتشي الترخيص.

وأعتقد أنه هو محلل البريد الإلكتروني الأكثر قدرة في جاوة، وأنا لم أرى واحدة أكثر قدرة في أي لغة، على الرغم من قد يكون هناك واحد من هناك. انها ليست محلل على غرار lexer، ولكن يستخدم بعض معقدة باستخدام التعابير المنطقية جافا، وبالتالي ليست فعالة كما أنها يمكن أن تكون، ولكن الشركة التي أعمل بها وتحليل أكثر من 10 مليارات عناوين في العالم الحقيقي معها: من المؤكد انها صالحة للاستعمال في عالية الأداء موقف. ربما مرة واحدة في السنة التي سوف تصل إلى العنوان الذي يؤدي إلى تجاوز التعابير المنطقية كومة (بشكل مناسب)، ولكن هذه هي عناوين البريد المزعج الذي المئات أو الآلاف من حرفا مع العديد من العديد من عروض الأسعار وأقواس وما شابه ذلك.

RFC 2822 و المواصفات ذات الصلة هي في الحقيقة متساهلة جدا من حيث عناوين البريد الإلكتروني، حتى فئة مثل هذا هو مبالغة بالنسبة لمعظم الاستخدامات. على سبيل المثال، ما يلي هو عنوان مشروعة، حسب المواصفات والمساحات وجميع:

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

ولا خادم البريد سيسمح ذلك، ولكن هذه الفئة يمكن تحليل ذلك (وإعادة كتابة إلى نموذج صالحة للاستعمال).

ولقد وجدنا الخيارات محلل جافا البريد الإلكتروني موجود لتكون دائمة بما فيه الكفاية (وهذا يعني، كل منهم لا يمكن تحليل بعض عناوين صالحة)، لذلك أنشأنا هذه الفئة.

والرمز هو موثقة جيدا و لديه الكثير من الخيارات سهلة التغيير إلى السماح أو عدم السماح بعض أشكال البريد الإلكتروني. كما أنه يوفر الكثير من الطرق للوصول إلى أجزاء معينة من عنوان (الجانب الأيسر، الجانب الأيمن، الأسماء الشخصية، والتعليقات، وغيرها)، تحليل / التحقق من صحة رؤوس علبة البريد القائمة، تحليل / التحقق من صحة مسار إرجاع (والتي هي فريدة من نوعها بين الرؤوس)، وهكذا دواليك.

والرمز كما هو مكتوب لها تبعية javamail، ولكن من السهل لإزالة إذا كنت لا تريد وظيفة بسيطة التي يقدمها.

وأنا أتساءل لماذا لا أحد يأتي مع <لأ href = "http://docs.jboss.org/hibernate/validator/5.1/reference/en-US/html/chapter-bean-constraints.html# مدقق-defineconstraints-HV-القيود "> @Email من قيود إضافية السبات المصادقة و. المدقق في حد ذاته هو EmailValidator .

لقد كتب لي HAZLEWOOD ودقيق جدا RFC 2822 بريد إلكتروني متوافق الطبقة المصادقة باستخدام جافا التعابير العادية. يمكنك العثور عليها في http://www.leshazlewood.com/؟p=23 . ومع ذلك، بدقتها (أو تنفيذ جافا RE) يؤدي إلى عدم الكفاءة - قراءة التعليقات حول تحليل مرات لعناوين طويلة

وأنا استدار بعض التعليمات البرمجية في 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 مع أنماط التعبير العادي للنطاقات العليا مختلفة (كبيرة جدا لتشمل:)

<idnlist>
    <idn>
        <tld>AC</tld>
        <pattern>^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AR</tld>
        <pattern>^[\u002d0-9a-zà-ãç-êìíñ-õü]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AS</tld>
        <pattern>/^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AT</tld>
        <pattern>/^[\u002d0-9a-zà-öø-ÿœšž]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>BIZ</tld>
        <pattern>^[\u002d0-9a-zäåæéöøü]{1,63}$</pattern>
        <pattern>^[\u002d0-9a-záéíñóúü]{1,63}$</pattern>
        <pattern>^[\u002d0-9a-záéíóöúüőű]{1,63}$</pattern>
    </id>
</idlist>
public class Validations {

    private Pattern regexPattern;
    private Matcher regMatcher;

    public String validateEmailAddress(String emailAddress) {

        regexPattern = Pattern.compile("^[(a-zA-Z-0-9-\\_\\+\\.)]+@[(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 = "suryaprakash.pisay@gmail.com";
        String mobileNumber = "+91-9986571622";
        Validations validations = new Validations();
        System.out.println(validations.validateEmailAddress(emailAddress));
        System.out.println(validations.validateMobileNumber(mobileNumber));
    }
}

على الرغم من وجود العديد من البدائل لمشاعات Apache، إلا أن تطبيقاتها بدائية في أحسن الأحوال (مثل تنفيذ مشاعات أباتشي نفسها) وحتى خطأ مميت في حالات أخرى.

سأبقى أيضًا بعيدًا عما يسمى بالتعبير العادي "غير المقيد" ؛لا يوجد شيء من هذا القبيل.على سبيل المثال @ مسموح به عدة مرات اعتمادًا على السياق، كيف تعرف أن المطلوب موجود؟لن يفهمه التعبير العادي البسيط، على الرغم من أن البريد الإلكتروني يجب أن يكون صالحًا.أي شئ أكثر تعقيدا يصبح معرض للخطأ أو حتى تحتوي قتلة الأداء الخفية.كيف أنت ذاهب للحفاظ على شيء من هذا القبيل هذا?

المدقق الشامل الوحيد المعتمد على regex والمتوافق مع RFC والذي أعرفه هو البريد الإلكتروني-rfc2822-المدقق مع التعبير العادي "المكرر" المسمى بشكل مناسب Dragons.java.وهو يدعم كبار السن فقط RFC-2822 على الرغم من أن المواصفات مناسبة بدرجة كافية للاحتياجات الحديثة (RFC-5322 التحديثات في مناطق خارج نطاق حالات الاستخدام اليومي).

لكن حقا ما تريد هو معجم الذي يوزع السلسلة بشكل صحيح ويقسمها إلى بنية المكون وفقًا لقواعد RFC. البريد الإلكترونيValidator4J تبدو واعدة في هذا الصدد، لكنها لا تزال شابة ومحدودة.

هناك خيار آخر لديك وهو استخدام خدمة ويب مثل خدمة Mailgun التي تم اختبارها في المعركة خدمة التحقق من صحة الويب أو واجهة برمجة تطبيقات Mailboxlayer (أخذت للتو نتائج Google الأولى).إنه ليس متوافقًا بشكل صارم مع RFC، ولكنه يعمل بشكل جيد بما يكفي لتلبية الاحتياجات الحديثة.

وماذا تريد التحقق من صحة؟ عنوان البريد الإلكتروني؟

ويمكن فقط أن يتم التحقق عنوان البريد الإلكتروني لمطابقة شكله. انظر المعيار: RFC2822 . أفضل طريقة للقيام بذلك هو تعبير عادي. وأنك لن تعرف إن وجدت حقا دون إرسال البريد الإلكتروني.

وراجعت المصادقة المشتركة. أنه يحتوي على الطبقة org.apache.commons.validator.EmailValidator. ويبدو أن نقطة انطلاق جيدة.

والحالي أباتشي العموم المصادقة الإصدار هو 1.3.1 .

وفئة من صحة هي org.apache.commons.validator.EmailValidator. ويحتوي على استيراد لorg.apache.oro.text.perl. Perl5Util وهو من مشروع جاكرتا ORO .

وراجع للشغل، وجدت أن هناك الإصدار 1.4، <وأ href = "http://commons.apache.org/validator/apidocs/org/apache/commons/validator/routines/EmailValidator.html" يختلط = " نوفولو "> وهنا API مستندات . على الموقع تقول: "آخر النشر: 5 مارس 2008 | الإصدار: 1.4 لقطة"، ولكن هذا ليس نهائيا. الطريقة الوحيدة لبناء نفسك (ولكن هذا هو لقطة، وليس الإصدار) والاستخدام، أو تحميل من <لأ href = "http://apache-commons.680414.n4.nabble.com/validator-download-1-4- نسخة td2298390.html "يختلط =" نوفولو "> هنا . وهذا يعني 1.4 لم يتخذ النهائي لمدة ثلاث سنوات (2008-2011). هذا ليس في الاسلوب أباتشي. أنا أبحث عن خيار أفضل، لكنها لم تجد واحد هو أن اعتمد جدا. أريد أن استخدام شيء أن يتم اختباره بشكل جيد، لا تريد ضرب أي البق.

وأنت قد تحتاج أيضا إلى التحقق من طول - رسائل البريد الإلكتروني هي بحد أقصى 254 حرف طويلة. يمكنني استخدام المصادقة المشتركة اباتشي وأنها لا تحقق لهذا الغرض.

وهناك لا يبدو أن هناك أي مكتبات مثالية أو طرق للقيام بذلك بنفسك، إلا إذا كان لديك لآخر لإرسال بريد إلكتروني إلى عنوان البريد الإلكتروني والانتظار للحصول على استجابة (وهذا قد لا يكون خيارا على الرغم من). انتهى بي الأمر باستخدام اقتراح من هنا HTTP: // blog.logichigh.com/2010/09/02/validating-an-e-mail-address/ وتعديل التعليمات البرمجية بحيث انها ستعمل في جاوة.

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

هذه هي أفضل طريقة:

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

وثمة خيار آخر هو استخدام في السبات البريد الإلكتروني مدقق ، وذلك باستخدام @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);
    }

}

وهيريس بلدي نهج عملي، حيث كنت فقط أريد عناوين متميزة نطاق بلاه @ معقولة باستخدام الأحرف المسموح بها من 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();
    }

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top