Quali sono le migliori pratiche per la convalida degli indirizzi e-mail su iOS 2.0


167

Qual è il modo più pulito per convalidare un indirizzo email che un utente inserisce su iOS 2.0?

NOTA : questa è una domanda storica specifica per iOS 2.0, a causa della sua età e di quante altre domande sono collegate ad essa, non può essere ritirata e NON DEVE essere cambiata in una domanda "moderna".


Sto cercando una soluzione di cacao. Comprendo la validità delle e-mail e le regole relative alla convalida delle e-mail. Tuttavia, poiché RegEx non è facilmente accessibile su Cocoa Touch, sto cercando una soluzione Cocoa Touch per la convalida. Non un elenco delle regole relative alla convalida.
Marcus S. Zarra,

Finora il miglior suggerimento sul codice che ho trovato è usare RegExKitLite ed espressioni regolari. Fortunatamente è meno doloroso di quanto sembri.
Marcus S. Zarra,

Vedere i commenti di seguito sull'utilizzo di NSRegularExpression per app che non supportano os <4.0.
entro il

1
Poiché questa sembra essere la domanda canonica relativa alla convalida dell'indirizzo e-mail, ha senso aggiornare con risposte migliorate man mano che iOS matura. Con questo in mente, ho aggiunto una risposta che utilizza iOS NSDataDetectordi indirizzi e-mail convalidate: stackoverflow.com/a/23547905/257550
memmons

2
Questa domanda sembra fuori tema perché riguarda iOS 2.0 che è stato deprecato anni fa.
Nathan Eror,

Risposte:


354

La risposta all'utilizzo di un'espressione regolare per convalidare un indirizzo e-mail spiega in dettaglio che la grammatica specificata in RFC 5322 è troppo complicata per le espressioni regolari primitive.

Raccomando un vero approccio parser come MKEmailAddress .

Come soluzione rapida per espressioni regolari vedere questa modifica di 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
Fantastico ma non funziona su OS <3.0, perché NSPredicate non è disponibile.
Felixyz,

4
Bello. Tutti dimenticano che NSPredicate può eseguire regexps.
Rog,

5
Questa è una regexp pessima. Ad esempio, fallirà sulle persone che usano il dominio principale .museum. Fare riferimento a questo articolo: linuxjournal.com/article/9585
Jonny il

18
C'è una regex più completa su cocoawithlove.com/2009/06/… che può essere utilizzata al posto di questa semplice.
Tomas Andrle,

12
Ecco una regex e-mail molto ingenua ma liberale come stringa Cocoa: @"[^@]+@[^.@]+(\\.[^.@]+)+"Se devi verificare un indirizzo e-mail, inviagli un messaggio e verifica se ha esito positivo. Non lo verificherai mai con un livello di precisione solo con una regex, quindi è meglio non pisciare sugli utenti e perdere le registrazioni a causa di una regex inutilmente rigorosa.
Sami Samhuri,

20

Leggi la RFC. Quasi tutti quelli che pensano di sapere come analizzare / pulire / convalidare un indirizzo e-mail hanno torto.

http://tools.ietf.org/html/rfc2822 La sezione 3.4.1 è molto utile. Avviso

dtext = NO-WS-CTL /; Controlli dello spazio non bianco

                        % d33-90 /; Il resto degli Stati Uniti-ASCII
                        % d94-126; caratteri che non includono "[",
                                        ; "]", o "\"

Sì, ciò significa che +, ', ecc. Sono tutti legittimi.


Attuale a maggio 2016: RFC5322, sezione 3.4.1
leanne,

17

La migliore soluzione che ho trovato finora (e quella con cui sono finito) è quella di aggiungere RegexKitLite al progetto che dà accesso alle espressioni regolari tramite le categorie NSString.

È abbastanza indolore da aggiungere al progetto e, una volta in atto, funzionerà una qualsiasi delle logiche di convalida delle e-mail con espressioni regolari.


5
NSPredicate può eseguire RegEx senza aggiungere ulteriori librerie al progetto.
BadPirate,

10
Questa domanda, dall'aprile del 2009, era prima che NSPredicate esistesse su iOS.
Marcus S. Zarra,

7
Ancora una volta, NSRegularExpression NON ESISTE in iOS 2.0 quando è stata posta questa domanda.
Marcus S. Zarra,

9
@Marcus, il punto di Stack Overflow non è quello di mantenere un registro storico di come particolari problemi sono stati risolti in passato. Detto questo, ho modificato la tua domanda per enfatizzare l'angolo di compatibilità 2.0.
benzado,

2
Si prega di leggere il titolo, questo è per iOS 2.0 che la soluzione Catlan non esisteva.
Marcus S. Zarra,

10

Un buon inizio è decidere cosa fai e non vuoi accettare come indirizzo email?

Il 99% degli indirizzi e-mail è simile al seguente: bob.smith@foo.com o fred@bla.edu

Tuttavia, è tecnicamente legale avere un indirizzo email come questo: f !#$%&'*+-/=?^_{|} ~ "ha!" @ Com

Probabilmente ci sono solo una manciata di e-mail valide al mondo per domini di primo livello, e quasi nessuno usa la maggior parte di quegli altri caratteri (in particolare virgolette e backtick), quindi potresti voler supporre che queste siano tutte cose non valide da fare. Ma dovresti farlo come una decisione consapevole.

Oltre a ciò, fai ciò che dice Paolo e prova a far corrispondere l'input a un'espressione regolare come questa: ^ [A-Z0-9 ._% + -] + @ [A-Z0-9 .-] +. [AZ] { 2,} $

Quello corrisponderà praticamente all'indirizzo e-mail di tutti.


anche se questa risposta è stata scritta nel 2009, risulta ancora molto alta nei risultati di ricerca. volevo solo aggiungere che questo non è più aggiornato e la regex sopra è un po 'restrittiva. ad esempio, ora puoi avere un dominio di massimo livello a 4 cifre
Jack

Buon punto, modificato in "almeno 2 cifre". Sentiti libero di modificare ulteriormente se vuoi.
Brandon Yarbrough,

7

L'attenzione per le espressioni regolari è buona, ma questo è solo un primo e necessario passo. Ci sono altri passaggi che devono anche essere considerati per una buona strategia di validazione.

Due cose in cima alla mia testa sono:

  1. Convalida DNS per assicurarsi che il dominio esista effettivamente.

  2. Dopo la convalida DNS, puoi anche scegliere di effettuare una convalida smtp. invia una chiamata al server smtp per vedere se l'utente esiste realmente.

In questo modo puoi rilevare tutti i tipi di errori dell'utente e assicurarti che sia un'e-mail valida.


7

Questa funzione è semplice e controlla l'indirizzo di posta elettronica in modo più approfondito. Ad esempio, secondo RFC2822, un indirizzo e-mail non deve contenere due punti consecutivi, come nome..lastname @ dominio..com

È anche importante utilizzare le ancore nelle espressioni regolari come si vede in questa funzione. Senza ancore il seguente indirizzo email è considerato valido: first; name) lastname@domain.com (blah perché la sezione lastname@domain.com è valida, ignorando prima; name) all'inizio e (blah alla fine. Anchors force force the motore di espressioni regolari per convalidare l'intera e-mail.

Questa funzione utilizza NSPredicate che non esiste in iOS 2. Sfortunatamente potrebbe non aiutare chi lo richiede, ma si spera che aiuterà gli altri con le versioni più recenti di iOS. Le espressioni regolari in questa funzione possono comunque essere applicate a RegExKitLite in iOS 2. E per coloro che usano iOS 4 o versioni successive, queste espressioni regolari possono essere implementate con 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];
}

Vedi validare l'indirizzo email usando l'espressione regolare in Objective-C .


iOS 2.0 non aveva NSPredicate.
Marcus S. Zarra,

2
Ma qual è l'uso di questa domanda e qual è l'uso di iOS 2. Stiamo avendo il sistema operativo più recente che è iOS 7.1. puoi anche usare 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

Ho scoperto che l'uso di un'espressione regolare funziona abbastanza bene per convalidare un indirizzo e-mail.

Il principale svantaggio delle espressioni regolari è ovviamente la manutenibilità, quindi commenta come non hai mai commentato prima. Te lo prometto, se non lo farai vorresti farlo quando tornerai all'espressione dopo alcune settimane.

Ecco un link a una buona fonte, http://www.regular-expressions.info/email.html .


Di recente ho implementato il penultimo su quella pagina e ne sono abbastanza contento. Funziona bene per un semplice indirizzo email user@host.com, senza virgolette o parentesi per un nome completo. Funziona alla grande per la convalida dei moduli web in cui le persone non scriveranno comunque quel genere di cose.
zombat,

2
Poveri con il loro TLD .museum.
BadPirate,

3

Scavando lo sporco, ma mi sono appena imbattuto in SHEmailValidator che fa un lavoro perfetto e ha una bella interfaccia.


Questa domanda era specifica per iOS 2.0 che non aveva NSPredicate o tutta una serie di altre cose che vengono utilizzate in quella libreria.
Marcus S. Zarra,

1
Lo so, ma sono atterrato qui prima mentre cercavo "convalida e-mail iOS". Forse qualche futuro me eseguirà la stessa ricerca e atterrerà qui e gli farà risparmiare un po 'di tempo.
Cyrille,

1

Molti siti Web forniscono RegExes, ma faresti bene a impararli e comprenderli, nonché a verificare che ciò che vuoi che faccia soddisfi le tue esigenze all'interno della RFC ufficiale per i formati di indirizzi e-mail.

Per l'apprendimento di RegEx, le lingue interpretate possono essere un ottimo semplificatore e banco di prova. Rubular è basato su Ruby, ma è un buon modo rapido per testare e verificare: http://www.rubular.com/

Oltre a ciò, acquista l'ultima edizione del libro O'Reilly Mastering Regular Expressions. Ti consigliamo di dedicare del tempo a comprendere i primi 3 o 4 capitoli. In seguito, tutto ciò costituirà una competenza sull'utilizzo altamente ottimizzato di RegEx.

Spesso una serie di RegEx più piccoli e più facili da gestire sono più facili da gestire ed eseguire il debug.


0

Ecco un'estensione di String che convalida un'e-mail in 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)
    }
}

Copiato dalla risposta a: Verifica che un indirizzo email sia valido su iOS


Non ce NSPredicaten'era su iOS 2.0
Marcus S. Zarra

-2

Non dovresti provare a usare regex per convalidare un'e-mail. Con i TLD in continua evoluzione, il tuo validatore è incompleto o impreciso. Invece, dovresti sfruttare le NSDataDetectorlibrerie di Apple che prenderanno una stringa e proveranno a vedere se ci sono campi di dati noti (e-mail, indirizzi, date, ecc.). L'SDK di Apple farà il duro lavoro per tenersi aggiornato con i TLD e si può tornare indietro dai loro sforzi !! :)

Inoltre, se iMessage (o qualsiasi altro campo di testo) non pensa che sia un'e-mail, dovresti prendere in considerazione un'e-mail?

Ho inserito questa funzione in una NSStringcategoria, quindi la stringa che stai testando è 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]]);
}

o come un rapido String estensione

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
Questa domanda è di OTTO anni fa.
Marcus S. Zarra,

1
Eppure, se tu Google validate email objective-c, questa domanda è il terzo risultato. Alcune cose su Internet non invecchiano. :-)
Craig Otis,

1
Si prega di interrompere i collegamenti spam a questa risposta sotto ogni post che è possibile trovare relativo alla convalida degli indirizzi e-mail. I commenti servono per richiedere chiarimenti, non per i collegamenti spam alle tue risposte.
meagar

A proposito, NSDataDetectorNON esisteva in iOS 2.0, che è di cosa si trattava / riguarda questa domanda.
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
Questa discussione / domanda è per iOS 2. NSPredicatenon esisteva in iOS 2; non è stato aggiunto fino a iOS 3.
Marcus S. Zarra

3
Ho risposto perché la tua risposta è sbagliata. La domanda è "come si fa X su iOS Y" e hai risposto con un framework che non esiste su quella versione di iOS.
Marcus S. Zarra,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.