İOS 2.0'da e-posta adreslerini doğrulamak için en iyi uygulamalar nelerdir


167

Bir kullanıcının iOS 2.0'da girdiği bir e-posta adresini doğrulamanın en temiz yolu nedir?

NOT : Bu, iOS 2.0'a özgü tarihsel bir sorudur ve yaşı ve diğer kaç soruyla bağlantılı olması nedeniyle emekli olamaz ve "modern" bir soru ile DEĞİŞTİRİLMEMELİDİR.


Bir kakao çözümü arıyorum. E-postaların geçerliliğini ve e-postaları doğrulama ile ilgili kuralları anlıyorum. Ancak RegEx'e Cocoa Touch'ta kolayca erişilemediğinden, doğrulama için bir Cocoa Touch çözümü arıyorum. Doğrulama ile ilgili kuralların bir listesi değil.
Marcus S. Zarra

Şimdiye kadar bulduğum en iyi kod önerisi RegExKitLite ve düzenli ifadeler kullanıyor. Neyse ki göründüğünden daha az acı verici.
Marcus S. Zarra

OS <4.0'ı desteklemeyen uygulamalar için NSRegularExpression kullanma hakkındaki aşağıdaki yorumlara bakın.
beon

1
Bu, e-posta adresi doğrulaması ile ilgili kanonik bir soru gibi göründüğünden, iOS olgunlaştıkça geliştirilmiş yanıtlarla güncelleme yapmak mantıklıdır. Bunu göz önünde bulundurarak, NSDataDetectore-posta adreslerini doğrulamak için
iOS'ları

2
Bu soru konu dışı gibi görünüyor çünkü yıllar önce kullanımdan kaldırılan iOS 2.0 hakkında.
Nathan Eror

Yanıtlar:


354

Bir e-posta adresini doğrulamak için normal bir ifade kullanma yanıtı , RFC 5322'de belirtilen dil bilgisinin ilkel normal ifadeler için çok karmaşık olduğunu ayrıntılı olarak açıklamaktadır.

MKEmailAddress gibi gerçek bir ayrıştırıcı yaklaşımı öneririm .

Hızlı düzenli ifadeler çözümü olarak DHValidation'ın bu değişikliğine bakın :

- (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
Harika, ancak OS <3.0'da çalışmaz, çünkü NSPredicate mevcut değildir.
Felixyz

4
Güzel. Herkes NSPredicate'in normal ifadeleri çalıştırabileceğini unutur.
Rog

5
Bu çok kötü bir ifade. Örneğin, .museum üst etki alanını kullanan kişilerde başarısız olur. Bu makaleye bakın: linuxjournal.com/article/9585
Jonny

18
Cocoawithlove.com/2009/06/… adresinde bu basit yerine kullanılabilecek daha eksiksiz bir normal ifade var.
Tomas Andrle

12
İşte bir kakao dizesi olarak çok naif ama liberal bir e-posta düzenli ifadesi: @"[^@]+@[^.@]+(\\.[^.@]+)+"Bir e-posta adresini doğrulamanız gerekiyorsa, ona bir mesaj gönderin ve başarılı olup olmadığını görün. Tek başına bir regex ile herhangi bir doğruluk seviyesiyle asla doğrulamayacaksınız, bu nedenle gereksiz sıkı sıkı bir regex nedeniyle kullanıcıları kızdırmamak ve kayıtlarını kaybetmemek en iyisidir.
Sami Samhuri

20

RFC'yi okuyun. Bir e-posta adresinin nasıl ayrıştırılacağını / temizleneceğini / doğrulanacağını bildiklerini düşünen neredeyse herkes yanlıştır.

http://tools.ietf.org/html/rfc2822 Bölüm 3.4.1 çok faydalıdır. Farkına varmak

dtext = NO-WS-CTL /; Beyaz boşluk olmayan kontroller

                        % d33-90 /; ABD-ASCII'nin geri kalanı
                        % d94-126; "[" içermeyen karakterler,
                                        ; "]" veya "\"

Evet, bunun anlamı +, 'vb. Yasaldır.


Mayıs 2016 itibarıyla geçerli: RFC5322, bölüm 3.4.1
leanne

17

Şimdiye kadar bulduğum en iyi çözüm (ve devam ettiğim çözüm) NSString Kategorileri aracılığıyla düzenli ifadelere erişim sağlayan projeye RegexKitLite eklemektir .

Projeye eklemek oldukça acısızdır ve bir kez yerleştirildikten sonra, normal ifade e-posta doğrulama mantığından herhangi biri işe yarayacaktır.


5
NSPredicate, projenize ek kitaplıklar eklemeden RegEx'i yapabilir.
BadPirate

10
Nisan 2009'dan itibaren bu soru, NSPredicate'in iOS'ta bulunmasından önce idi.
Marcus S. Zarra

7
Yine, bu soru sorulduğunda NSRegularExpression iOS 2.0'da OLMADI .
Marcus S. Zarra

9
@Marcus, Stack Overflow'un amacı, geçmişte belirli sorunların nasıl çözüldüğüne dair tarihsel bir kayıt tutmak değildir. Bununla birlikte, 2.0 uyumluluk açısını vurgulamak için sorunuzu düzenledim.
benzado

2
Lütfen başlığı okuyun, bu Catlan'ın çözümü olmayan iOS 2.0 içindir.
Marcus S. Zarra

10

İyi bir başlangıç, neyi ve e-posta adresi olarak kabul etmek istemediğinize karar vermektir.

E-posta adreslerinin% 99'u şuna benzer: bob.smith@foo.com veya fred@bla.edu

Ancak, bunun gibi bir e-posta adresine sahip olmak teknik olarak yasaldır: f !#$%&'*+-/=?^_{|} ~ "ha!" @ Com

Muhtemelen dünyada üst düzey alanlar için sadece bir avuç geçerli e-posta var ve neredeyse hiç kimse bu diğer karakterlerin çoğunu (özellikle tırnak işaretleri ve backticks) kullanmıyor, bu nedenle bunların hepsinin geçersiz şeyler olduğunu varsaymak isteyebilirsiniz. Ama bunu bilinçli bir karar olarak yapmalısınız.

Bunun ötesinde, Paul'ün söylediklerini yapın ve girdiyi şu şekilde normal bir ifadeyle eşleştirmeye çalışın: ^ [A-Z0-9 ._% + -] + @ [A-Z0-9 .-] +. [AZ] { 2,} $

Bu, herkesin e-posta adresiyle hemen hemen eşleşecek.


Bu cevap 2009 yılında yazılmış olmasına rağmen, arama sonuçlarında hala çok yüksek. sadece bu artık güncel değildir ve yukarıdaki normal ifade biraz kısıtlayıcı olduğunu eklemek istedim. örneğin, şimdi 4 basamaklı veya daha fazla üst düzey alana sahip olabilirsiniz
Jack

İyi bir nokta, "en az 2 basamak" olarak düzenledi. İsterseniz daha fazla düzenleme yapmaktan çekinmeyin.
Brandon Yarbrough

7

Düzenli ifadelere odaklanmak iyi olsa da, bu sadece ilk ve gerekli bir adımdır. İyi bir doğrulama stratejisi için dikkate alınması gereken başka adımlar da vardır.

Başımın üstünde iki şey var:

  1. Etki alanının gerçekten var olduğundan emin olmak için DNS doğrulaması.

  2. DNS doğrulamasından sonra bir smtp doğrulaması yapmayı da seçebilirsiniz. kullanıcının gerçekten var olup olmadığını görmek için smtp sunucusuna bir çağrı gönderin.

Bu şekilde her türlü kullanıcı hatasını yakalayabilir ve geçerli bir e-posta olduğundan emin olabilirsiniz.


7

Bu işlev basittir ve e-posta adresini daha ayrıntılı bir şekilde kontrol eder. Örneğin, RFC2822'ye göre, bir e-posta adresi arka arkaya iki ad içermemelidir, örneğin ad.sonadı @ domain..com

Bu işlevde görüldüğü gibi düzenli ifadelerde çapa kullanmak da önemlidir. Bağlantılar olmadan aşağıdaki e-posta adresi geçerli olarak kabul edilir: ad; ad) lastname@domain.com (blah , lastname@domain.com bölümü geçerli olduğundan, ad göz ardı edilerek ; ad) başlangıçta ve (blah sonda). tüm e-postaları doğrulamak için normal ifadeler motoru.

Bu işlev iOS 2'de bulunmayan NSPredicate'i kullanıyor. Maalesef askere yardımcı olmayabilir, ancak umarım diğerlerine iOS'un yeni sürümlerinde yardımcı olur. Bu işlevdeki normal ifadeler yine de iOS 2'de RegExKitLite'a uygulanabilir. İOS 4 veya üstünü kullananlar için bu düzenli ifadeler NSRegularExpression ile uygulanabilir.

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

Bkz . Objective-C'deki normal ifadeyi kullanarak e-posta adresini doğrulama .


iOS 2.0'da NSPredicate yoktu.
Marcus S. Zarra

2
Ama bu sorunun ne kullanımı ve ios 2'nin kullanımı nedir. İos 7.1 olan en son işletim sistemine sahibiz. ios 6'yı da kullanabilirsiniz.
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

Normal bir ifade kullanmanın bir e-posta adresini doğrulamak için oldukça iyi çalıştığını gördüm.

Düzenli ifadelerin en büyük dezavantajı elbette sürdürülebilirliktir, bu yüzden daha önce hiç yorum yapmadığınız gibi yorum yapın. Size söz veriyorum, eğer yapmazsanız, birkaç hafta sonra ifadeye geri döndüğünüzde bunu yapmayı dilersiniz.

İşte iyi bir kaynağın bağlantısı: http://www.regular-expressions.info/email.html .


Son zamanlarda bu sayfada ikinci olanı uyguladım ve bundan oldukça memnunum. Tam bir isim için tırnak veya parantez olmadan basit bir user@host.com e-posta adresi için iyi çalışır. İnsanların bu tür şeyleri zaten yazamayacakları web form doğrulaması için harika çalışıyor.
zombat

2
.Museum TLD'si ile fakir insanlar.
BadPirate

3

Kir kazmak, ama ben sadece mükemmel bir iş yapar ve güzel bir arayüze sahip SHEmailValidator tökezledi .


Bu soru, NSPredicate'e sahip olmayan iOS 2.0'a veya bu kütüphanede kullanılan başka pek çok şeye özgüdür.
Marcus S. Zarra

1
Biliyorum, ama önce "ios e-posta doğrulaması" ararken buraya indim. Belki gelecekteki bazı kişiler burada aynı aramayı yapmalı ve buraya inecek ve onu biraz zaman kurtaracak.
Cyrille

1

Birçok web sitesi RegExes sağlar, ancak bunları öğrenmek ve anlamak ve yapmak istediğiniz şeyin e-posta adresi formatları için resmi RFC'de ihtiyaçlarınızı karşıladığını doğrulamak iyi olur.

RegEx'i öğrenmek için, yorumlanmış diller çok daha basit ve test edilmiş olabilir. Rubular Ruby üzerine kurulmuştur, ancak test etmenin ve doğrulamanın iyi bir hızlı yoludur: http://www.rubular.com/

Bunun ötesinde, O'Reilly Mastering Regular Expressions kitabının en son sürümünü satın alın. İlk 3 veya 4 bölümü anlamak için zaman harcamak isteyeceksiniz. Bundan sonraki her şey son derece optimize edilmiş RegEx kullanımı konusunda uzmanlık yaratacak.

Çoğu zaman RegExes'in daha küçük, yönetilmesi daha kolay bir dizi bakımı ve hata ayıklaması daha kolaydır.


0

Burada, Swift'te bir e-postayı doğrulayan bir String uzantısı var.

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

Yanıttan şuraya kopyalandı: iOS'ta bir e-posta adresinin geçerli olup olmadığını kontrol edin


NSPredicate
İOS

-2

Bir e-postayı doğrulamak için regex kullanmaya çalışmamalısınız. Sürekli değişen TLD'lerle doğrulayıcınız eksik veya yanlış. Bunun yerine, NSDataDetectorbir dize alacak ve bilinen veri alanlarının (e-postalar, adresler, tarihler, vb.) Olup olmadığını görmeye çalışan Apple'ın kitaplıklarından yararlanmalısınız . Apple'ın SDK'sı TLD'lerle güncel kalmanın ağır yükünü kaldıracak ve çabalarını geri çekebilirsiniz !! :)

Ayrıca, iMessage (veya başka bir metin alanı) bunun bir e-posta olduğunu düşünmüyorsa, bir e-posta mı düşünmelisiniz?

Bu işlevi bir NSStringkategoriye koydum , bu yüzden test ettiğiniz dize self.

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

veya hızlı bir Stringuzantı olarak

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
Bu soru Sekiz yıl öncesindendir.
Marcus S. Zarra

1
Ve yine de, Google iseniz validate email objective-c, bu soru üçüncü sonuçtur. İnternetteki bazı şeyler yaşlanmaz. :-)
Craig Otis

1
Lütfen, e-posta adreslerini doğrulama ile ilgili bulabileceğiniz her gönderinin altında bu cevaba yönelik spam bağlantılarını durdurun. Yorumlar, yanıt istemek için değil, açıklama istemek içindir.
meagar

BTW, NSDataDetectoriOS 2.0'da bu sorunun ne olduğu / ne hakkında olduğu yoktu.
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
Bu konu / soru iOS 2 içindir. İOS 2'de NSPredicatemevcut değildi; iOS 3'e kadar eklenmedi
Marcus S. Zarra

3
Cevap verdim çünkü cevabınız yanlış. Soru "iOS Y'de X'i nasıl yapıyorsunuz" ve bu iOS sürümünde bulunmayan bir çerçeveyle cevapladınız.
Marcus S. Zarra
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.