วิธีการตรวจสอบที่อยู่อีเมล Java ที่ดีที่สุดคืออะไร? [ปิด]


247

ไลบรารีการตรวจสอบความถูกต้องของที่อยู่อีเมลที่ดีสำหรับ Java คืออะไร มีทางเลือกอื่นในการตรวจสอบความถูกต้องของคอมมอนส์หรือไม่?


15
ฉันจะออกจากที่นี่: davidcelis.com/blog/2012/09/06/…
mpenkov

4
URL ปัจจุบันสำหรับ Commons: commons.apache.org/proper/commons-validator/apidocs/org/apache/
......

คุณไม่ควรต้องการใช้ไลบรารี (หรือ regexes) ที่ไม่ได้ตรวจสอบอย่างละเอียด เนื่องจากความซับซ้อนของที่อยู่อีเมลที่ถูกต้องจึงไม่มีเหตุผลตรงกลางระหว่างการตรวจสอบและการตรวจสอบที่ครอบคลุม การใช้งาน Apache Commons นั้นไม่ครอบคลุม ฉันรู้ว่ามีเพียงหนึ่งไลบรารีที่เป็น ( email-rfc2822-validator ) แต่ก็ยังใช้งานได้กับ regexes ขนาดใหญ่ lexer ที่ครอบคลุมคือสิ่งที่คุณต้องการ EmailValidator4Jบอกว่าใช้งานได้ แต่ฉันไม่มีประสบการณ์
Benny Bottema

1
@BennyBottema แทนที่จะแก้ไขคำถามด้วยคำอธิบายโปรดทำโพสต์ Meta เพื่อหารือเกี่ยวกับสาเหตุที่ปิดถ้าคุณยังมีคำถาม
Machavity

คำตอบ:


134

Apache Commons เป็นที่รู้จักกันโดยทั่วไปว่าเป็นโครงการที่แข็งแกร่ง อย่างไรก็ตามโปรดทราบว่าคุณจะต้องส่งอีเมลยืนยันไปยังที่อยู่หากคุณต้องการให้แน่ใจว่าเป็นอีเมลจริงและเจ้าของต้องการให้ใช้ในเว็บไซต์ของคุณ

แก้ไข : มีข้อผิดพลาดที่ จำกัด โดเมนมากเกินไปทำให้ไม่รับอีเมลที่ถูกต้องจาก TLD ใหม่

ข้อผิดพลาดนี้ได้รับการแก้ไขเมื่อวันที่ 03 / Jan / 15 02:48 ในคอมมอนส์ - ตรวจสอบรุ่น 1.4.1


1
ฉันเห็นด้วยกับบิตพิเศษที่คุณอ้างถึง แต่เป็นส่วนหนึ่งของโครงการตรวจสอบคอมมอนส์หรือไม่
duffymo

2
ไม่EmailValidatorคลาสApache ไม่ส่งข้อความอีเมลเพื่อการตรวจสอบ
Matthew Flaschen

3
หากกรณีการใช้งานของคุณคือการตรวจสอบที่อยู่อีเมลระยะไกลของผู้ใช้โซลูชันนี้มีข้อบกพร่องมากมาย (คล้ายกับ InternetAddress.validate ()): EmailValidator พิจารณาว่า user @ [10.9.8.7] เป็นที่อยู่อีเมลที่ถูกต้องซึ่งเป็นไปตาม RFC แต่อาจไม่ใช่สำหรับการลงทะเบียนผู้ใช้ / แบบฟอร์มการติดต่อ
zillion1

1
@zillion ที่มีการบันทึกไว้ใน Apache COmmons: "การใช้งานนี้ไม่รับประกันว่าจะได้รับข้อผิดพลาดที่เป็นไปได้ทั้งหมดในที่อยู่อีเมล" และฉันก็บอกว่าคุณต้องทำอย่างไรเพื่อ "ทำให้แน่ใจว่าเป็นอีเมลจริง" แม้ว่าที่อยู่ที่มี IP ท้องถิ่นอาจใช้ได้ในสภาพแวดล้อมที่หายาก
Matthew Flaschen

5
Apache Commons EmailValidator มีข้อเสียอย่างหนึ่ง: ไม่รองรับ IDN
Piohen

261

การใช้แพ็คเกจอีเมล 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;
}

59
โปรดทราบว่า InternetAddress.validate () พิจารณาว่า user @ [10.9.8.7] และ user @ localhost เป็นที่อยู่อีเมลที่ถูกต้องซึ่งเป็นไปตาม RFC แม้ว่าขึ้นอยู่กับกรณีการใช้งาน (แบบฟอร์มเว็บ) คุณอาจต้องการที่จะปฏิบัติต่อพวกเขาว่าไม่ถูกต้อง
zillion1

8
ไม่เพียงเท่านั้นที่ถูกต้องตามที่ @ zillion1 กล่าว แต่ยังมีสิ่งต่างๆเช่น bla @ bla ที่ถือว่าใช้ได้ ไม่ใช่ทางออกที่ดีที่สุดจริงๆ
Diego Plentz

4
@NicholasTolleyCottrell นี่คือ Java ที่นี่เราโยนและจับข้อยกเว้นฉันไม่ได้รับคะแนนของคุณ
gyorgyabraham

17
ฉันสงสัยว่าตัวสร้างที่อยู่อินเทอร์เน็ตได้รับการดัดแปลง หรือระบบของฉันถูกดัดแปลง หรือ RFC822 ได้รับการดัดแปลงด้วย หรือตอนนี้ฉันสามารถนอนหลับได้แล้ว แต่ฉันเพิ่งลองใช้รหัสบางส่วนและห้าสายต่อไปนี้ทั้งหมดผ่านเป็นที่อยู่อีเมลที่ถูกต้องถ้าคุณส่งพวกเขาไปยังตัวสร้าง InternetAddress และ "ชัดเจน" พวกเขาจะไม่ถูกต้อง ที่นี่เราไป: ., .com, com., และabc 123นอกจากนี้การเพิ่มช่องว่างนำหน้าหรือต่อท้ายจะไม่ทำให้สตริงใช้งานไม่ได้ คุณเป็นผู้ตัดสิน!
Martin Andersson

4
อืม, ชีสล้มเหลวอย่างถูกต้องเมื่อฉันเรียกใช้ สิ่งที่คุณกำลังเชื่อมโยงไปยังห้องสมุด javax.mail
Aaron Davidson

91

ตัวตรวจสอบ 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 = "myName@example.com";
boolean valid = EmailValidator.getInstance().isValid(email);

และเพื่ออนุญาตที่อยู่ในพื้นที่

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

2
ใน Android Studio คุณสามารถเพิ่มคอมไพล์ 'commons-validator: commons-validator: 1.4.1' ในแอปของคุณ \ build.gradle การพึ่งพาของ {}
Benjiko99

2
หลังจากพยายามสร้างโครงการของฉันจริง ๆ แล้วดูเหมือนว่า apache คอมมอนส์ไม่สามารถใช้งานกับ Android ได้ดีคำเตือนหลายร้อยคำและข้อผิดพลาดบางอย่างก็ไม่ได้รวบรวม นี่คือสิ่งที่ฉันลงเอยด้วยการใช้howtodoinjava.com/2014/11/11/java-regex-validate-email-address
Benjiko99

1
ปัญหาเดียวกันกับฉันในฐานะของ Benjiko99 หลังจากเพิ่มการพึ่งพาแล้วโครงการจะไม่คอมไพล์โดยกล่าวว่า java.exe เสร็จสิ้นโดยไม่มีรหัสการออกเป็นศูนย์ 2
Amit Mittal

1
ฉันได้รับข้อผิดพลาดใน Android Studio เช่นกัน ฉันเปลี่ยนจาก 1.4.1 เป็น 1.5.1 และใช้งานได้!
Matt

1
หมายเหตุ: Use_the Emailvalidator ใน org.apache.commons.validator.routines ตั้งแต่ EmailValidator ใน org.apache.commons.validator เลิกใช้งานแล้ว (ฉันใช้ตัวตรวจสอบความถูกต้อง 1.6 คอมมอนส์)
HopeKing

71

คำตอบที่ล่าช้า แต่ฉันคิดว่ามันง่ายและมีค่า:

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

กรณีทดสอบ :

ป้อนคำอธิบายรูปภาพที่นี่

เพื่อจุดประสงค์ในการผลิตการตรวจสอบความถูกต้องของชื่อโดเมนควรดำเนินการผ่านเครือข่าย


40
นั่นเป็นเครื่องมือตรวจสอบที่เรียบง่ายอย่างไร้ความปราณีที่ละเว้นกฎ RFC ส่วนใหญ่พร้อมกับ IDN ฉันขอแนะนำอย่างชัดเจนสำหรับแอปคุณภาพการผลิต
mlaccetti

1
me@company.co.uk จะไม่ถูกต้อง ...
Alexander Burakevych

14
อย่าม้วนตัวตรวจสอบที่ใช้ regex ของคุณเองสำหรับสิ่งที่ครอบคลุมโดย RFC
Josh Glover

6
reinventing ล้อก็โอเคตราบใดที่คุณไม่สนใจยางแบนเป็นครั้งคราว
dldnh

มันเป็นเรื่องดี แต่ไม่ใช่สำหรับทุกกรณี
Andrain

21

หากคุณกำลังพยายามทำการตรวจสอบแบบฟอร์มที่ได้รับจากลูกค้าหรือเพียงแค่การตรวจสอบความถูกต้องของถั่ว - ทำให้มันง่าย จะเป็นการดีกว่าถ้าคุณทำการตรวจสอบอีเมลแบบหลวม ๆ แทนที่จะทำการตรวจสอบอีเมลที่เข้มงวดและปฏิเสธบางคน (เช่นเมื่อพวกเขาพยายามลงทะเบียนสำหรับบริการเว็บของคุณ) ด้วยเกือบทุกอย่างที่ได้รับอนุญาตในส่วนชื่อผู้ใช้ของอีเมลและโดเมนใหม่จำนวนมากถูกเพิ่มเข้ามาอย่างแท้จริงทุกเดือน (เช่น .company, .entreprise, .estate) จึงปลอดภัยกว่าไม่ จำกัด :

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

3
นี้เป็นจุดที่ดีจริงๆแอปที่เหมาะสมควรจะมีมาตรการอื่น ๆ เพื่อป้องกันไม่ให้การป้อนข้อมูลนี้จากการถูกเอาเปรียบลงเส้นอยู่แล้ว
jmaculate

4
ลองเปลี่ยนเป็น "^. + @. + (\\. [^ \\.] +) + $" เพื่อหลีกเลี่ยงจุดต่อท้าย?
Xingang Huang

7

มาสายคำถามที่นี่ แต่: ฉันรักษาชั้นเรียนตามที่อยู่นี้: http://lacinato.com/cm/software/emailrelated/emailaddress

มันขึ้นอยู่กับชั้นเรียนของ Les Hazlewood แต่มีการปรับปรุงและแก้ไขข้อบกพร่องจำนวนมาก ใบอนุญาต Apache

ฉันเชื่อว่าเป็นตัวแยกวิเคราะห์อีเมลที่มีความสามารถมากที่สุดใน Java และฉันยังไม่ได้เห็นความสามารถในภาษาใด ๆ อีกแม้ว่าจะมีตัวแปลออกมาหนึ่งตัว มันไม่ใช่ parser แบบ lexer แต่ใช้ java regex ที่ซับซ้อนบางตัวและดังนั้นมันจึงไม่ได้มีประสิทธิภาพเท่าที่ควร แต่ บริษัท ของฉันได้ทำการแยกวิเคราะห์ที่อยู่ของโลกแห่งความเป็นจริงมากกว่า 10,000 ล้านที่อยู่: มันสามารถใช้งานได้อย่างมีประสิทธิภาพสูง สถานการณ์. บางทีปีละครั้งมันจะเข้าสู่ที่อยู่ที่ทำให้เกิดการล้นกอง regex (เหมาะสม) แต่เหล่านี้เป็นที่อยู่สแปมที่มีหลายร้อยหรือหลายพันตัวอักษรยาวกับคำพูดมากมายและวงเล็บจำนวนมากและไม่ชอบ

RFC 2822และสเปคที่เกี่ยวข้องนั้นได้รับอนุญาตจริงๆในแง่ของที่อยู่อีเมลดังนั้นคลาสเช่นนี้จึงมีราคาแพงเกินไปสำหรับการใช้งานส่วนใหญ่ ตัวอย่างเช่นต่อไปนี้เป็นที่อยู่ที่ถูกต้องตามช่องว่างและทั้งหมด:

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

ไม่มีเมลเซิร์ฟเวอร์ที่จะอนุญาต แต่คลาสนี้สามารถแยกวิเคราะห์ได้ (และเขียนลงในแบบฟอร์มที่ใช้งานได้)

เราพบว่าตัวแยกวิเคราะห์อีเมล Java ที่มีอยู่มีความทนทานไม่เพียงพอ (ความหมายทั้งหมดนั้นไม่สามารถแยกที่อยู่ที่ถูกต้องบางส่วนได้) ดังนั้นเราจึงสร้างคลาสนี้ขึ้นมา

รหัสนี้มีเอกสารครบถ้วนและมีตัวเลือกมากมายที่ง่ายต่อการเปลี่ยนแปลงเพื่ออนุญาตหรือไม่อนุญาตให้ใช้แบบฟอร์มอีเมลบางอย่าง นอกจากนี้ยังมีวิธีการมากมายในการเข้าถึงบางส่วนของที่อยู่ (ด้านซ้าย, ด้านขวา, ชื่อบุคคล, ความคิดเห็น, ฯลฯ ), ในการแยก / ตรวจสอบส่วนหัวของรายการกล่องจดหมายเพื่อแยก / ตรวจสอบเส้นทางกลับ (ซึ่งเป็นเอกลักษณ์ในส่วนหัว) และอื่น ๆ

รหัสตามที่เขียนมีการพึ่งพา javamail แต่มันง่ายที่จะลบหากคุณไม่ต้องการฟังก์ชั่นย่อยที่มีให้


1
สวัสดีฉันคัดลอกลงใน GitHub เพื่อเผยแพร่สู่ชุมชนโอเพนซอร์ส ตอนนี้ทุกคนสามารถแสดงความคิดเห็นเอกสารและปรับปรุงรหัส github.com/bbottema/email-rfc2822-validator ฉันเคยใช้รุ่นเก่าโดย Les แต่ฉันต้องลบออกเนื่องจากข้อผิดพลาดการแช่แข็ง regex: leshazlewood.com/2006/11/06/emailaddress-java-class/ …
Benny Bottema

7

ฉันแค่สงสัยว่าทำไมไม่มีใครมาด้วย@Emailจากข้อ จำกัด เพิ่มเติมของ Hibernate Validator EmailValidatorตรวจสอบตัวเองเป็น


แม้ว่าจะเป็นทางเลือกให้กับ Apache ทั่วไป แต่การใช้งานก็เป็นพื้นฐานเช่นเดียวกับไลบรารีที่ใช้ regex ส่วนใหญ่ จากเอกสาร: "อย่างไรก็ตามในขณะที่บทความนี้กล่าวถึงมันไม่จำเป็นที่จะใช้ตัวตรวจสอบอีเมลที่ได้มาตรฐาน 100%" ตัวตรวจสอบที่ครอบคลุมโดยใช้ regex เพียงอย่างเดียวที่ฉันรู้จักคือemail-rfc2822-validatorและอย่างอื่นEmailValidator4Jดูเหมือนว่าจะมีแนวโน้ม
Benny Bottema

5

Les Hazlewood ได้เขียนคลาสตัวตรวจสอบอีเมลที่ตรงตามมาตรฐาน RFC 2822 โดยใช้นิพจน์ทั่วไปของ Java คุณสามารถค้นหาได้ที่http://www.leshazlewood.com/?p=23 อย่างไรก็ตามการทั่วถึง (หรือการนำ Java RE มาใช้) นำไปสู่การไร้ประสิทธิภาพ - อ่านความคิดเห็นเกี่ยวกับการแยกเวลาสำหรับที่อยู่ยาว


1
ฉันสร้างชั้นเรียนที่ดีเยี่ยมของ Les Hazlewood (ซึ่งมีข้อบกพร่องบางอย่าง) (ดูคำตอบที่แยกต่างหากสำหรับคำถามนี้) แม้ว่าฉันจะรักษาวิธี java regex ไว้ แต่เราก็ใช้งานได้ดีในสภาพแวดล้อมที่มีความสำคัญต่อประสิทธิภาพ หากสิ่งที่คุณกำลังทำคือการแยกที่อยู่ประสิทธิภาพอาจเป็นปัญหา แต่สำหรับผู้ใช้ส่วนใหญ่ฉันสงสัยว่ามันเป็นเพียงจุดเริ่มต้นของสิ่งที่พวกเขากำลังทำ การอัปเดตชั้นเรียนของฉันยังแก้ไขปัญหาการสอบถามซ้ำหลายครั้ง
lacinato

นี้เป็นห้องสมุดเก่าและได้ถูกแทนที่สองครั้งในที่สุดโดยอีเมล RFC2822-ตรวจสอบ แม้ว่ามันจะยังคงเหมาะกับความต้องการที่ทันสมัยทั้งหมด แต่ก็ยังมีแนวโน้มที่จะมีข้อบกพร่องด้านประสิทธิภาพที่ซ่อนอยู่ (และไม่รองรับการเปลี่ยนแปลงที่ จำกัด โดยข้อกำหนด RFC ที่ใหม่กว่า)
Benny Bottema

3

ฉันย้ายรหัสบางส่วนใน 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();
    }
}

ด้วยชื่อโฮสต์ validator ดังต่อไปนี้:

@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 ที่มีรูปแบบ regex สำหรับ tlds ที่แตกต่างกัน (ใหญ่เกินไปที่จะรวม :)

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

คำตอบนี้ไม่สามารถใช้งานได้อีกต่อไปด้วยเหตุผลที่ชัดเจน ลบการตรวจสอบความถูกต้อง TLD และอาจเป็นที่ยอมรับได้หากคุณต้องการยอมรับที่อยู่อีเมลที่ไม่ใช่ภาษาอังกฤษ
Christopher Schneider

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

2

หากคุณต้องการตรวจสอบว่าที่อยู่อีเมลนั้นถูกต้องVRFYจะช่วยคุณได้ ฉันพบว่ามันมีประโยชน์สำหรับการตรวจสอบที่อยู่อินทราเน็ต (นั่นคือที่อยู่อีเมลสำหรับเว็บไซต์ภายใน) อย่างไรก็ตามมีประโยชน์น้อยกว่าสำหรับเซิร์ฟเวอร์จดหมายทางอินเทอร์เน็ต (ดูคำเตือนที่ด้านบนของหน้านี้)


2

แม้ว่าจะมีทางเลือกมากมายสำหรับ Apache ทั่วไปการใช้งานของพวกเขาเป็นพื้นฐานที่ดีที่สุด (เช่นการใช้งาน Apache Commonsเอง) และแม้แต่ตายผิดในกรณีอื่น ๆ

ฉันยังอยู่ห่างจาก regex ง่าย ๆ ที่เรียกว่า 'ไม่ จำกัด '; ไม่มีสิ่งนั้น ตัวอย่างเช่น@ ได้รับอนุญาตหลายครั้งขึ้นอยู่กับบริบทคุณจะรู้ได้อย่างไรว่าสิ่งที่จำเป็นต้องมี? Simple regex จะไม่เข้าใจแม้ว่าอีเมลควรจะถูกต้อง อะไรที่ซับซ้อนมากขึ้นจะกลายเป็นข้อผิดพลาดหรือแม้กระทั่งมีฆาตกรต่อประสิทธิภาพการทำงานที่ซ่อนอยู่ คุณจะรักษาบางสิ่งเช่นนี้อย่างไร

RFC สอดคล้อง regex ตรวจสอบตามที่ครอบคลุมเพียงฉันรู้คืออีเมล RFC2822-ตรวจสอบกับ 'กลั่น' regex ชื่อที่เหมาะสมDragons.java รองรับเฉพาะรุ่นเก่าRFC-2822แม้ว่าจะเหมาะสมพอสำหรับความต้องการที่ทันสมัย ​​(RFC-5322 อัปเดตในพื้นที่ที่อยู่นอกขอบเขตสำหรับกรณีการใช้งานประจำวัน)

แต่สิ่งที่คุณต้องการจริงๆคือ lexerที่แยกวิเคราะห์สตริงและแบ่งออกเป็นโครงสร้างส่วนประกอบตามไวยากรณ์ RFC อย่างถูกต้อง EmailValidator4Jดูเหมือนจะมีแนวโน้มในเรื่องนั้น แต่ก็ยังเด็กและ จำกัด

อีกตัวเลือกหนึ่งที่คุณใช้คือการใช้เว็บเซอร์วิซเช่นการตรวจสอบความถูกต้องของการทดสอบการต่อสู้ของMailgunหรือMailboxlayer API (เพิ่งรับผลการค้นหาครั้งแรกของ Google) ไม่สอดคล้องกับ RFC อย่างเคร่งครัด แต่ทำงานได้ดีพอสำหรับความต้องการที่ทันสมัย


1

คุณต้องการตรวจสอบสิ่งใด ที่อยู่อีเมล?

ที่อยู่อีเมลสามารถตรวจสอบได้สำหรับรูปแบบที่สอดคล้อง ดูมาตรฐาน: RFC2822 วิธีที่ดีที่สุดในการทำเช่นนั้นคือการแสดงออกปกติ คุณจะไม่มีทางรู้ว่ามีตัวตนจริงหรือไม่ถ้าไม่ส่งอีเมล

ฉันตรวจสอบตัวตรวจสอบคอมมอนส์ มันมีคลาส org.apache.commons.validator.EmailValidator ดูเหมือนจะเป็นจุดเริ่มต้นที่ดี


ฉันไม่แน่ใจว่า regex เป็นวิธีที่ดีที่สุดในการทำเช่นนั้นมันค่อนข้างอ่านไม่ออกถ้าคุณตั้งใจจะติดตาม RFC ไปที่จดหมาย
2813274

เห็นด้วยกับ @ user2813274 คุณต้องการ lexer ที่เหมาะสมไม่ใช่ spaghetti regex
Benny Bottema

1

รุ่นปัจจุบัน Apache Commons Validator เป็น1.3.1

คลาสที่ตรวจสอบความถูกต้องคือ org.apache.commons.validator.EmailValidator มีการนำเข้าสำหรับ org.apache.oro.text.perl.Perl5Utilซึ่งมาจากโครงการ ORO จาการ์ตาที่เกษียณแล้ว

BTW ผมพบว่ามีรุ่น 1.4 นี่เป็นเอกสารของ API บนเว็บไซต์มีข้อความระบุว่า: "เผยแพร่ครั้งล่าสุด: 5 มีนาคม 2551 | เวอร์ชั่น: 1.4-SNAPSHOT" แต่นั่นไม่ใช่ครั้งสุดท้าย วิธีเดียวที่จะสร้างตัวเอง ( แต่นี้เป็นภาพรวมไม่ปล่อย) และการใช้งานหรือดาวน์โหลดได้จากที่นี่ ซึ่งหมายความว่า 1.4 ยังไม่สิ้นสุดในสามปี (2551-2554) นี่ไม่ใช่ในสไตล์ของ Apache ฉันกำลังมองหาตัวเลือกที่ดีกว่า แต่ไม่พบตัวเลือกที่มีการใช้งานมาก ฉันต้องการใช้สิ่งที่ผ่านการทดสอบอย่างดีไม่ต้องการที่จะมีข้อบกพร่องใด ๆ


1.4 SNAPSHOT ยังต้องการ Jakarta ORO เครื่องมือตรวจสอบ Apache Commons ไม่สามารถใช้งานได้สำหรับฉัน
หมอกใน

ในที่สุดก็เลือก Dr.Vet วิธีการแก้ปัญหาของ Cumpanasu Florin: mkyong.com/regular-expressions/…
หมอกเมื่อ

1
ฉันยอมรับว่าตัวตรวจสอบ Apache Commons ทำงานได้ดี แต่ฉันคิดว่ามันค่อนข้างช้า - มากกว่า 3ms ต่อการโทรหนึ่งครั้ง
Nic Cottrell

การแสดงนั้นไม่สำคัญสำหรับฉัน
หมอก

ลำตัวปัจจุบัน SNAPSHOT (SVN REV 1227719 ณ ตอนนี้) ไม่มีการพึ่งพาภายนอกเช่น ORO อีกต่อไป - คุณไม่จำเป็นต้องใช้โมดูลการตรวจสอบความถูกต้องทั้งหมดอีกต่อไป - org.apache.commons.validator.routines, DomainValidator และ InetAddressValidator RegexValidator สามารถยืนอยู่คนเดียว
Jörg

0

คุณอาจต้องการตรวจสอบความยาว - อีเมลมีความยาวไม่เกิน 254 ตัวอักษร ฉันใช้ apache commons validator และมันไม่ได้ตรวจสอบสิ่งนี้


RFC 2821 สปีชีส์ (ส่วน 4.5.3.1) ระบุlocal-partความยาว 64 และdomainความยาว 255 (พวกเขาบอกว่าซอฟต์แวร์ที่ได้รับอนุญาตอาจถูกปฏิเสธโดยซอฟต์แวร์อื่นได้อีกต่อไป)
sarnold

-2

ดูเหมือนจะไม่มีห้องสมุดที่สมบูรณ์แบบหรือวิธีการทำสิ่งนี้ด้วยตัวเองเว้นแต่คุณจะต้องใช้เวลาในการส่งอีเมลไปยังที่อยู่อีเมลและรอการตอบกลับ (นี่อาจไม่ใช่ตัวเลือก) ฉันลงเอยด้วยการใช้คำแนะนำจากที่นี่ http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/ และปรับรหัสเพื่อให้ทำงานได้ใน Java

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

-2

นี่เป็นวิธีที่ดีที่สุด:

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


-2

ตัวเลือกอื่นคือใช้ตัวตรวจสอบความถูกต้องอีเมลของไฮเบอร์เนตโดยใช้คำอธิบายประกอบ@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);
    }

}

ทำไมต้องลงคะแนน? เป็นคลาสเดียวกับที่ใช้โดย Hibernate Validator
Dherik

-3

นี่เป็นวิธีปฏิบัติของฉันที่ฉันต้องการที่อยู่โดเมน 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();
    }

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.