แนวทางปฏิบัติที่ดีที่สุดสำหรับการตรวจสอบความถูกต้องของที่อยู่อีเมลใน iOS 2.0


167

วิธีที่ปลอดภัยที่สุดในการตรวจสอบความถูกต้องของที่อยู่อีเมลที่ผู้ใช้ป้อนใน iOS 2.0 คืออะไร

หมายเหตุ : นี่เป็นคำถามเชิงประวัติศาสตร์ที่เฉพาะเจาะจงกับ iOS 2.0 และเนื่องจากอายุและคำถามอื่น ๆ ที่เชื่อมโยงกับคำถามนั้นไม่สามารถยกเลิกได้และจะต้องไม่เปลี่ยนเป็นคำถาม "ทันสมัย"


ฉันกำลังมองหาวิธีการแก้ปัญหาโกโก้ ฉันเข้าใจความถูกต้องของอีเมลและกฎระเบียบเกี่ยวกับการตรวจสอบอีเมล อย่างไรก็ตามเนื่องจาก RegEx ไม่สามารถเข้าถึงได้อย่างง่ายดายบน Cocoa Touch ฉันกำลังมองหาโซลูชัน Cocoa Touch เพื่อตรวจสอบความถูกต้อง ไม่ใช่รายการของกฎเกี่ยวกับการตรวจสอบ
Marcus S. Zarra

จนถึงตอนนี้คำแนะนำเกี่ยวกับโค้ดที่ดีที่สุดที่ฉันพบคือใช้ RegExKitLite และนิพจน์ทั่วไป โชคดีที่มันเจ็บปวดน้อยกว่าที่มันฟัง
Marcus S. Zarra

ดูความคิดเห็นด้านล่างเกี่ยวกับการใช้ NSRegular Expression สำหรับแอปที่ไม่รองรับระบบปฏิบัติการ <4.0
beOn

1
เนื่องจากนี่เป็นคำถามที่ยอมรับได้เกี่ยวกับการตรวจสอบความถูกต้องของที่อยู่อีเมลจึงสมควรปรับปรุงด้วยคำตอบที่ดีขึ้นเมื่อ iOS ครบกำหนด โดยที่ในใจฉันได้เพิ่มคำตอบที่ใช้ของ iOS ในNSDataDetectorการตรวจสอบที่อยู่อีเมล: stackoverflow.com/a/23547905/257550
memmons

2
คำถามนี้ดูเหมือนจะไม่ได้อยู่ในหัวข้อเพราะเป็นเรื่องเกี่ยวกับ iOS 2.0 ซึ่งเลิกใช้เมื่อหลายปีก่อน
Nathan Eror

คำตอบ:


354

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

ฉันแนะนำวิธีการแยกวิเคราะห์จริงเช่น MKEmailAddress

ในฐานะที่เป็นวิธีการแก้ปัญหาการแสดงผลปกติอย่างรวดเร็วเห็นการปรับเปลี่ยนนี้ DHValidation :

- (BOOL) validateEmail: (NSString *) candidate {
    NSString *emailRegex =
@"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-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])+)\\])"; 
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", emailRegex]; 

    return [emailTest evaluateWithObject:candidate];
}

9
ยอดเยี่ยม แต่ไม่ทำงานบน OS <3.0 เนื่องจาก NSPredicate ไม่พร้อมใช้งาน
Felixyz

4
ดี ทุกคนลืมว่า NSPredicate สามารถเรียกใช้ regexps
Rog

5
นั่นเป็นหนึ่งใน regexp ที่แย่มาก ๆ ตัวอย่างเช่นมันจะล้มเหลวในผู้ใช้โดเมน. top พิพิธภัณฑ์ อ้างถึงบทความนี้: linuxjournal.com/article/9585
จอนนี่

18
มี regex ที่สมบูรณ์มากขึ้นที่cocoawithlove.com/2009/06/…ที่สามารถใช้แทนแบบง่าย ๆ นี้ได้
Tomas Andrle

12
นี่คือ regex อีเมลที่ไร้เดียงสา แต่เสรีนิยมเป็นสตริง Cocoa: @"[^@]+@[^.@]+(\\.[^.@]+)+"หากคุณต้องการตรวจสอบที่อยู่อีเมลส่งข้อความถึงมันและดูว่าสำเร็จหรือไม่ คุณจะไม่ยืนยันด้วยระดับความแม่นยำใด ๆ กับ regex เพียงอย่างเดียวดังนั้นจึงเป็นการดีที่สุดที่จะไม่ฉี่ผู้ใช้และสูญเสียการสมัครใช้งานเนื่องจาก regex ที่เข้มงวดโดยไม่จำเป็น
Sami Samhuri

20

อ่าน RFC เกือบทุกคนที่คิดว่าพวกเขารู้วิธีแยก / ล้าง / ตรวจสอบที่อยู่อีเมลผิด

http://tools.ietf.org/html/rfc2822 มาตรา 3.4.1 มีประโยชน์มาก แจ้งให้ทราบ

dtext = NO-WS-CTL /; ไม่มีการควบคุมพื้นที่สีขาว

                        % d33-90 /; ส่วนที่เหลือของ US-ASCII
                        % d94-126; อักขระไม่รวม "[",
                                        ; "]", หรือ "\"

ใช่นั่นหมายถึง +, 'และอื่น ๆ ล้วน แต่ถูกต้อง


ปัจจุบัน ณ เดือนพฤษภาคม 2016 RFC5322 ส่วน 3.4.1
ลีแอนน์

17

ทางออกที่ดีที่สุดที่ฉันพบ (และสิ่งที่ฉันจบลงด้วย) คือการเพิ่มRegexKitLiteให้กับโครงการที่ให้การเข้าถึงนิพจน์ทั่วไปผ่าน NSString Categories

มันค่อนข้างเจ็บปวดที่จะเพิ่มเข้าไปในโครงการและเมื่อใดก็ตามที่ตรรกะการตรวจสอบอีเมลนิพจน์ปกติใด ๆ จะทำงาน


5
NSPredicate สามารถทำ RegEx โดยไม่ต้องเพิ่มไลบรารีเพิ่มเติมในโครงการของคุณ
BadPirate

10
คำถามนี้ตั้งแต่เดือนเมษายนปี 2009 ก่อนที่ NSPredicate จะมีอยู่ใน iOS
Marcus S. Zarra

7
อีกครั้ง NSRegularExpression ไม่ได้มีอยู่ใน iOS 2.0 เมื่อมีการถามคำถามนี้
Marcus S. Zarra

9
@ Marcus จุดของ Stack Overflow ไม่ใช่เพื่อรักษาบันทึกทางประวัติศาสตร์ว่ามีการแก้ไขปัญหาเฉพาะในอดีตอย่างไร ที่กล่าวว่าฉันได้แก้ไขคำถามของคุณเพื่อเน้นมุมความเข้ากันได้ 2.0
benzado

2
โปรดอ่านชื่อเรื่องนี้มีไว้สำหรับ iOS 2.0 ซึ่งโซลูชันของ Catlan ไม่มีอยู่
Marcus S. Zarra

10

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

ที่อยู่อีเมล 99% มีลักษณะเช่นนี้: bob.smith@foo.com หรือ fred@bla.edu

อย่างไรก็ตามเป็นเรื่องถูกต้องทางเทคนิคที่จะมีที่อยู่อีเมลเช่นนี้: f !#$%&'*+-/=?^_{|} ~ "ha!" @ com

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

ทำสิ่งที่ Paul พูดแล้วลองจับคู่อินพุตกับนิพจน์ทั่วไปดังนี้ ^ [A-Z0-9 ._% + -] + @ [A-Z0-9 .-] + [AZ] { 2} $

อันนั้นจะตรงกับที่อยู่อีเมลของทุกคน


แม้ว่าคำตอบนี้ถูกเขียนขึ้นในปี 2009 แต่ก็ยังมีผลการค้นหาที่สูงมาก ฉันแค่อยากจะเพิ่มว่านี้ไม่ทันสมัยและ regex ข้างต้นเป็นข้อ จำกัด เล็กน้อย ตัวอย่างเช่นตอนนี้คุณสามารถมี 4 หลักหรือมากกว่าโดเมนระดับบนสุด
แจ็ค

จุดดีแก้ไขเป็น "อย่างน้อย 2 หลัก" หากต้องการแก้ไขเพิ่มเติม
Brandon Yarbrough

7

ในขณะที่การมุ่งเน้นไปที่การแสดงออกปกติเป็นสิ่งที่ดี แต่นี่เป็นเพียงขั้นตอนแรกและจำเป็น มีขั้นตอนอื่น ๆ ที่ต้องคำนึงถึงกลยุทธ์การตรวจสอบที่ดี

สองสิ่งที่อยู่บนหัวของฉันคือ:

  1. การตรวจสอบความถูกต้อง DNS เพื่อให้แน่ใจว่าโดเมนนั้นมีอยู่จริง

  2. หลังจากการตรวจสอบความถูกต้อง DNS คุณยังสามารถเลือกทำการตรวจสอบ smtp ส่งการเรียกไปยังเซิร์ฟเวอร์ smtp เพื่อดูว่ามีผู้ใช้จริงหรือไม่

ด้วยวิธีนี้คุณสามารถตรวจจับข้อผิดพลาดของผู้ใช้ทุกประเภทและตรวจสอบว่าเป็นอีเมลที่ถูกต้อง


7

ฟังก์ชั่นนี้ใช้ง่ายและยังตรวจสอบที่อยู่อีเมลให้ละเอียดยิ่งขึ้น ตัวอย่างเช่นตาม RFC2822 ที่อยู่อีเมลจะต้องไม่มีจุดสองจุดในหนึ่งแถวเช่น firstname..lastname @ domain..com

สิ่งสำคัญคือต้องใช้จุดยึดในนิพจน์ทั่วไปตามที่เห็นในฟังก์ชั่นนี้ ที่อยู่อีเมลต่อไปนี้จะถือว่าไม่มีผล: First; name) lastname@domain.com (blahเนื่องจากส่วนlastname@domain.comถูกต้องโดยไม่สนใจfirst; name)ที่จุดเริ่มต้นและ(blahที่จุดสิ้นสุด Anchors บังคับให้ กลไกการแสดงผลปกติเพื่อตรวจสอบอีเมลทั้งหมด

ฟังก์ชั่นนี้ใช้ NSPredicate ซึ่งไม่มีอยู่ใน iOS 2 น่าเสียดายที่มันอาจจะไม่ช่วยผู้ถาม แต่หวังว่าจะช่วยคนอื่นด้วย iOS เวอร์ชั่นใหม่กว่า นิพจน์ทั่วไปในฟังก์ชันนี้ยังสามารถใช้กับ RegExKitLite ใน iOS 2 ได้ และสำหรับผู้ที่ใช้ iOS 4 หรือใหม่กว่านิพจน์ทั่วไปเหล่านี้สามารถนำไปใช้กับ NSRegularExpression

- (BOOL)isValidEmail:(NSString *)email
{
    NSString *regex1 = @"\\A[a-z0-9]+([-._][a-z0-9]+)*@([a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,4}\\z";
    NSString *regex2 = @"^(?=.{1,64}@.{4,64}$)(?=.{6,100}$).*";
    NSPredicate *test1 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex1];
    NSPredicate *test2 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex2];
    return [test1 evaluateWithObject:email] && [test2 evaluateWithObject:email];
}

ดูที่อยู่อีเมลตรวจสอบโดยใช้การแสดงออกปกติใน Objective-C


iOS 2.0 ไม่มี NSPredicate
Marcus S. Zarra

2
แต่การใช้คำถามนี้คืออะไรและการใช้ ios 2 คืออะไรเรามีระบบปฏิบัติการล่าสุดนั่นคือ iOS 7.1 คุณสามารถใช้ iOS 6 ได้ด้วย
Gaurav Gilani

6
NSString *emailString = textField.text; **// storing the entered email in a string.** 
**// Regular expression to checl the email format.** 
NSString *emailReg = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",emailReg]; 
if (([emailTest evaluateWithObject:emailString] != YES) || [emailStringisEqualToString:@""]) 
{ 
UIAlertView *loginalert = [[UIAlertView alloc] initWithTitle:@" Enter Email in" message:@"abc@example.com format" delegate:self 
cancelButtonTitle:@"OK" otherButtonTitles:nil]; 

enter code here

[loginalert show]; 
[loginalert release]; 
} 
If email is invalid, it will remind the user with an alert box. 
Hope this might be helpful for you all. 

4

ฉันพบว่าการใช้นิพจน์ทั่วไปนั้นใช้งานได้ค่อนข้างดีในการตรวจสอบที่อยู่อีเมล

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

นี่คือการเชื่อมโยงไปยังแหล่งที่ดีhttp://www.regular-expressions.info/email.html


ฉันเพิ่งใช้งานครั้งที่สองในหน้านั้นเมื่อไม่นานมานี้และฉันมีความสุขมากกับมัน มันใช้งานได้ดีสำหรับที่อยู่อีเมล user@host.com อย่างง่ายโดยไม่มีเครื่องหมายอัญประกาศหรือวงเล็บสำหรับชื่อเต็ม ใช้งานได้ดีสำหรับการตรวจสอบความถูกต้องของฟอร์มเว็บที่ผู้คนจะไม่พิมพ์สิ่งนั้นใน
zombat

2
คนจนด้วย. พิพิธภัณฑ์ TLD
BadPirate

3

ขุดดิน แต่ฉันเพิ่งสะดุดกับSHEmailValidatorซึ่งทำงานได้อย่างสมบูรณ์แบบและมีส่วนต่อประสานที่ดี


คำถามนี้เฉพาะกับ iOS 2.0 ที่ไม่มี NSPredicate หรือโฮสต์ทั้งหมดของสิ่งอื่น ๆ ที่ใช้ในไลบรารีนั้น
Marcus S. Zarra

1
ฉันรู้ แต่ฉันลงจอดที่นี่ก่อนในขณะที่ค้นหา "การตรวจสอบอีเมล ios" บางทีในอนาคตฉันจะทำการค้นหาและลงจอดที่นี่และมันจะช่วยเขาซักครั้ง
Cyrille

1

เว็บไซต์จำนวนมากให้บริการ RegExes แต่คุณต้องเรียนรู้และเข้าใจอย่างดีรวมถึงตรวจสอบว่าสิ่งที่คุณต้องการให้ตรงกับความต้องการของคุณภายใน RFC อย่างเป็นทางการสำหรับรูปแบบที่อยู่อีเมล

สำหรับการเรียนรู้ RegEx ภาษาที่ตีความแล้วอาจเป็นเครื่องขยายเสียงและทดสอบที่ดีเยี่ยม Rubular สร้างขึ้นจาก Ruby แต่เป็นวิธีที่รวดเร็วในการทดสอบและตรวจสอบ: http://www.rubular.com/

นอกจากนั้นซื้อหนังสือ O'Reilly Mastering Regular Expressions รุ่นล่าสุด คุณจะต้องใช้เวลาในการทำความเข้าใจ 3 หรือ 4 บทแรก ทุกอย่างหลังจากนั้นจะเป็นการสร้างความเชี่ยวชาญในการใช้ RegEx ที่ได้รับการปรับให้เหมาะสม

บ่อยครั้งที่ชุดของ RegExes ที่เล็กลงและง่ายต่อการจัดการจะง่ายต่อการบำรุงรักษาและดีบัก


0

นี่คือส่วนขยายของ String ที่ตรวจสอบอีเมลใน Swift

extension String {

    func isValidEmail() -> Bool {
        let stricterFilter = false
        let stricterFilterString = "^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$"
        let laxString = "^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2}[A-Za-z]*$"
        let emailRegex = stricterFilter ? stricterFilterString : laxString
        let emailTest = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
}

คัดลอกจากคำตอบไปที่: ตรวจสอบว่าที่อยู่อีเมลนั้นถูกต้องบน iOS


ไม่มีNSPredicateใน iOS 2.0
Marcus S. Zarra

-2

คุณไม่ควรลองใช้ regex เพื่อตรวจสอบอีเมล ด้วยการเปลี่ยน TLDs เครื่องมือตรวจสอบของคุณจะไม่สมบูรณ์หรือไม่ถูกต้อง แต่คุณควรใช้ประโยชน์จากNSDataDetectorห้องสมุดของ Apple ซึ่งจะใช้สตริงและลองดูว่ามีเขตข้อมูลที่รู้จัก (อีเมลที่อยู่วันที่ ฯลฯ ) หรือไม่ SDK ของ Apple จะยกระดับการติดตาม TLD อย่างหนักและคุณสามารถนำความพยายามออกมาได้ !! :)

นอกจากนี้หาก iMessage (หรือช่องข้อความอื่น ๆ ) ไม่คิดว่าเป็นอีเมลคุณควรพิจารณาอีเมลหรือไม่

ฉันใส่ฟังก์ชั่นนี้ในหมวดหมู่เพื่อให้สายที่คุณกำลังทดสอบคือNSStringself

- (BOOL)isValidEmail {
    // Trim whitespace first
    NSString *trimmedText = [self stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];
    if (self && self.length > 0) return NO;

    NSError *error = nil;
    NSDataDetector *dataDetector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:&error];
    if (!dataDetector) return NO;

    // This string is a valid email only if iOS detects a mailto link out of the full string
    NSArray<NSTextCheckingResult *> *allMatches = [dataDetector matchesInString:trimmedText options:kNilOptions range:NSMakeRange(0, trimmedText.length)];
    if (error) return NO;
    return (allMatches.count == 1 && [[[allMatches.firstObject URL] absoluteString] isEqual:[NSString stringWithFormat:@"mailto:%@", self]]);
}

หรือเป็นStringส่วนขยายที่รวดเร็ว

extension String {
    func isValidEmail() -> Bool {
        let trimmed = self.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty, let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
            return false
        }
        let allMatches = dataDetector.matches(in: trimmed, options: [], range: NSMakeRange(0, trimmed.characters.count))

        return allMatches.count == 1 && allMatches.first?.url?.absoluteString == "mailto:\(trimmed)"
    }
}

1
คำถามนี้มาจากแปดปีที่ผ่านมา
Marcus S. Zarra

1
และถ้าคุณเป็น Google validate email objective-cคำถามนี้คือผลลัพธ์ที่สาม บางสิ่งบนอินเทอร์เน็ตไม่แก่ :-)
Craig Otis

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

BTW NSDataDetectorไม่มีอยู่ใน iOS 2.0 ซึ่งเป็นคำถามนี้ / เป็นเรื่องเกี่ยวกับ
Marcus S. Zarra

-7
// Method Call
NSString *email = @"Your Email string..";

BOOL temp = [self validateEmail:email];

if(temp)
{
// Valid
}
else
{
// Not Valid
}
// Method description

- (BOOL) validateEmail: (NSString *) email {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    BOOL isValid = [emailTest evaluateWithObject:email];
    return isValid;
}

3
กระทู้ / คำถามนี้สำหรับ iOS 2 NSPredicateไม่มีอยู่ใน iOS 2 มันไม่ได้ถูกเพิ่มเข้ามาจนกระทั่ง iOS 3
Marcus S. Zarra

3
ฉันตอบเพราะคำตอบของคุณผิด คำถามคือ "คุณจะทำ X บน iOS Y ได้อย่างไร" และคุณตอบด้วยเฟรมเวิร์กที่ไม่มีอยู่ใน iOS เวอร์ชันนั้น
Marcus S. Zarra
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.