Bagaimana cara memvalidasi alamat email dengan cepat?

338

Adakah yang tahu cara memvalidasi alamat email di Swift? Saya menemukan kode ini:

- (BOOL) validEmail:(NSString*) emailString {

    if([emailString length]==0){
        return NO;
    }

    NSString *regExPattern = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";

    NSRegularExpression *regEx = [[NSRegularExpression alloc] initWithPattern:regExPattern options:NSRegularExpressionCaseInsensitive error:nil];
    NSUInteger regExMatches = [regEx numberOfMatchesInString:emailString options:0 range:NSMakeRange(0, [emailString length])];

    NSLog(@"%i", regExMatches);
    if (regExMatches == 0) {
        return NO;
    } else {
        return YES;
    }
}

tapi saya tidak bisa menerjemahkannya ke Swift.

Giorgio Nocera
sumber
8
terjemahan harus jelas. bagian apa yang memberimu masalah?
Sulthan
12
Jangan lupa berdoa bahwa tidak ada pengguna Anda yang memiliki domain tingkat atas yang baru. Misalnya.coffee
Matthias Bauch
1
@ Antzi: Saya memeriksa dengan "seseorang @ gmail" dan regex Anda kembali benar.
Đông An
2
Regex tidak berfungsi untuk memvalidasi bahwa pengguna telah memasukkan alamat email mereka. Satu-satunya cara yang benar 100% adalah mengirim email aktivasi. Lihat: Saya Tahu Cara Memvalidasi Alamat Email Sampai Saya Baca RFC
mouviciel
2
Ini adalah QA yang menarik. Ini hampir pasti QA "paling salah" di seluruh situs. Jawaban # 1 saat ini dengan 600 suara (apa ?!) benar-benar, salah, dalam segala hal yang mungkin (setiap jalur individu benar-benar salah, dan setiap konsep dan ide salah ........ !!!) Banyak jawaban yang sangat banyak dipilihnya adalah "benar-benar salah", "sangat buruk", atau, benar-benar rusak dan bahkan tidak dapat dikompilasi. Lebih lanjut, sementara sifat dari Q ini menyerukan "teknik regex elit" banyak jawaban (sangat memilih!) Fitur teknik regex yang mengerikan. Ini QA yang sangat menarik !! Mengapa??
Fattie

Jawaban:

769

Saya akan menggunakan NSPredicate:

func isValidEmail(_ email: String) -> Bool {        
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"

    let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
    return emailPred.evaluate(with: email)
}

untuk versi Swift lebih awal dari 3.0:

func isValidEmail(email: String) -> Bool {
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"

    let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
    return emailPred.evaluate(with: email)
}

untuk versi Swift lebih awal dari 1.2:

func isValidEmail(email: String) -> Bool {
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"

    if let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx) {
        return emailPred.evaluateWithObject(email)
    }
    return false
}
Maxim Shoustin
sumber
6
tidak return emailTest.evaluateWithObject(testStr)akan jauh lebih sederhana dan mudah dibaca? Dibandingkan dengan == truesedikit seperti Javascript.
Sulthan
15
Itu tidak memeriksa apakah ada ekstensi yang tersedia, a @ a sudah OK :(
CularBytes
6
ini tidak berlaku untuk test @ test ... com
Alan
3
Ini tidak mendeteksi email. @ Invalid.com atau email @ .invalid.com. Jawaban di bawah dari @alexcristea tidak
Ben Sullivan
3
Sangat lucu bahwa ............ serta (1) regex sama sekali, benar-benar salah (2) regex (bahkan dalam konteks apa yang coba dilakukan) memiliki kesalahan besar ( 3) Swift salah (4) bahkan mengesampingkan itu, gayanya benar-benar salah (5) tidak penting mengingat sisanya, tetapi bahkan tidak menyebutkan bahwa Anda harus men - cache predikat ... lucu, ( 6) masih ada sisa kode ("kalender" - apa?) Dari mana pun ia disalin.
Fattie
115

Pengeditan, diperbarui untuk Swift 3:

func validateEmail(enteredEmail:String) -> Bool {

    let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
    return emailPredicate.evaluate(with: enteredEmail)

}

Jawaban asli untuk Swift 2:

func validateEmail(enteredEmail:String) -> Bool {

    let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
    return emailPredicate.evaluateWithObject(enteredEmail)

}

Ini bekerja dengan baik.

Azik Abdullah
sumber
2
yang pertama dengan regex yang valid. yang lain memvalidasi aa @ aach to true
netshark1000
1
@ netshark1000, hanya dengan upvotes, jawaban apa pun akan ada di atas. :)
Azik Abdullah
NSRegularExpression lebih mudah digunakan daripada NSPredicate
Guillaume Laurent
1
Itu tidak menangani kondisi dua titik setelah nama domain. coba jawaban ini stackoverflow.com/a/53441176/5032981
Prashant Gaikwad
@AzikAbdullah Jika Anda memasukkan 'abc @ gmail..com' maka itu juga akan divalidasi
Nij
110

Sebagai String ekstensi kelas

SWIFT 4

extension String {
    func isValidEmail() -> Bool {
        // here, `try!` will always succeed because the pattern is valid
        let regex = try! NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", options: .caseInsensitive)
        return regex.firstMatch(in: self, options: [], range: NSRange(location: 0, length: count)) != nil
    }
}

Pemakaian

if "rdfsdsfsdfsd".isValidEmail() {

}
Arsonik
sumber
4
countElementssekarangcount
Zack Shapiro
25
xxx @ yyy kembali benar?
Cullen SUN
1
Sama seperti Cullen SUN, foo @ bar mengembalikan true.
Rémy Virin
3
user @ host tanpa .tld juga alamat email yang valid, mis. root @ localhost
Rab
1
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
64

Jika Anda mencari solusi yang bersih dan sederhana untuk melakukan ini, Anda harus melihat di https://github.com/nsagora/validation-components .

Ini berisi predikat validasi email yang mudah diintegrasikan dalam kode Anda:

let email = "[email protected]"
let rule = EmailValidationPredicate()
let isValidEmail = rule.evaluate(with: email)

Di balik kapnya menggunakan RFC 5322 reg ex ( http://emailregex.com ):

let regex = "(?:[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[\\p{L}0-9!#$%\\&'*+/=?\\^_`{|}" +
    "~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\" +
    "x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[\\p{L}0-9](?:[a-" +
    "z0-9-]*[\\p{L}0-9])?\\.)+[\\p{L}0-9](?:[\\p{L}0-9-]*[\\p{L}0-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]?|[\\p{L}0-9-]*[\\p{L}0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21" +
    "-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"
alexcristea
sumber
3
Wow, tidak tahu tentang emailregex.com. Itu luar biasa!
Samuel Ev
2
Akhirnya, yang menyaring email. @. Email.com
Ben Sullivan
ini bekerja dengan tepat - [email protected]. itu tidak memvalidasi abc @ abc
Anil Gupta
Ah, Akhirnya ..: D
Ümañg ßürmån
39

Inilah solusi yang masuk akal:

"SOLUSI YANG WAJAR"

Digunakan dan diuji selama bertahun-tahun di banyak aplikasi volume besar.

1 - itu menghindari banyak kesalahan regex mengerikan yang sering Anda lihat dalam saran ini

2 - TIDAK mengizinkan email bodoh seperti "x @ x" yang dianggap valid di bawah RFC tertentu, tetapi benar-benar konyol, tidak dapat digunakan sebagai email, dan staf pendukung Anda akan langsung menolak, dan yang semuanya layanan mailer (mailchimp, google, aws, dll) cukup ditolak. Jika (karena alasan tertentu) Anda membutuhkan solusi yang memungkinkan string seperti 'x @ x', gunakan solusi lain.

3 - kode ini sangat, sangat, sangat bisa dimengerti

4 - ini KISS, dapat diandalkan, dan diuji untuk penghancuran pada aplikasi komersial dengan jumlah pengguna yang sangat besar

5 - poin teknis, predikatnya adalah global, seperti yang dikatakan Apple (perhatikan saran kode yang tidak memiliki ini)

let __firstpart = "[A-Z0-9a-z]([A-Z0-9a-z._%+-]{0,30}[A-Z0-9a-z])?"
let __serverpart = "([A-Z0-9a-z]([A-Z0-9a-z-]{0,30}[A-Z0-9a-z])?\\.){1,5}"
let __emailRegex = __firstpart + "@" + __serverpart + "[A-Za-z]{2,8}"
let __emailPredicate = NSPredicate(format: "SELF MATCHES %@", __emailRegex)

extension String {
    func isEmail() -> Bool {
        return __emailPredicate.evaluate(with: self)
    }
}

extension UITextField {
    func isEmail() -> Bool {
        return self.text!.isEmail()
    }
}

Sangat mudah.

Penjelasan:

Dalam uraian berikut, "OC" berarti karakter biasa - huruf atau angka.

__firstpart ... harus memulai dan mengakhiri dengan OC. Untuk karakter di tengah Anda dapat memiliki karakter tertentu seperti garis bawah, tetapi awal dan akhir harus menjadi OC. (Namun, tidak apa - apa memiliki hanya satu OC dan hanya itu, misalnya: [email protected])

__serverpart ... Anda memiliki bagian seperti "bla." yang berulang . (Jadi jenis mail.city.fcu.edu.) Bagian harus dimulai dan diakhiri dengan OC, tetapi di tengah Anda juga dapat memiliki tanda hubung "-". (Jika Anda ingin mengizinkan karakter tidak biasa lainnya di sana, mungkin garis bawah, cukup tambahkan sebelum tanda hubung.) Tidak apa - apa untuk memiliki bagian yang hanya satu OC. (Seperti dalam [email protected]) Anda dapat memiliki hingga lima bagian, Anda harus memiliki satu. Akhirnya TLD (seperti .com) secara ketat 2-8 di ukuran . Jelas, ubah saja "8" itu seperti yang disukai oleh departemen dukungan Anda.


PENTING !

Anda harus mempertahankan predikat sebagai global, jangan membangunnya setiap saat.

Perhatikan bahwa ini adalah hal pertama yang Apple sebutkan tentang keseluruhan masalah dalam dokumen.

Sangat mengejutkan ketika Anda melihat saran yang tidak menyembunyikan predikat.

Fattie
sumber
1
Apakah ini mendukung TLD baru seperti .engineer?
Roman
hai @Roman - perhatikan di mana tertulis "Akhirnya TLD (.com atau sejenisnya) benar-benar 2 hingga 8 huruf." Itu yang mengurusnya. Anda dapat mengubah "8" ke nilai yang Anda inginkan. (Untuk saat ini, di banyak perusahaan besar, layanan pelanggan hanya akan menolak TLD panjang hanya sebagai penipuan - tapi, itu keputusan Anda, gunakan "8" atau nilai apa pun yang Anda suka.)
Fattie
2
Berkenaan dengan poin (4): bagaimana Anda menguji dengan banyak pengguna? Apakah Anda melacak pengguna, yang tidak dapat mendaftar dengan aplikasi komersial, karena regex tidak mencegah mereka menggunakan alamat email mereka? Satu-satunya yang "masuk akal" seharusnya, apa yang spec (RFC) tentukan atau jika ini tidak dapat dicapai, maka sesuatu yang lebih santai, tetapi mencakup semuanya dari spec. Jika pengguna tidak diizinkan untuk memasukkan x @ x, mereka akan memasukkan beberapa [email protected] yang akan melewati / regex Anda.
thetrutz
hi @thetrutz, "[email protected]" adalah alamat email yang benar-benar normal. RFC mencakup kebodohan teoretis seperti "x @ x". setiap klien komersial Anda atau saya pernah bekerja akan mengatakan "larang itu". (perhatikan bahwa dalam bisnis besar dunia nyata mana pun, ada jauh lebih banyak batasan daripada garis besar kasar saya di sini, seperti yang saya sebutkan dalam komentar di atas untuk Roman.) Kalimat terakhir Anda membingungkan - tentu saja "email yang tidak berfungsi" akan melewati semua tes lokal? Maksud kamu apa? Jelas email pada akhirnya hanya diverifikasi melalui sistem "konfirmasi email Anda".
Fattie
Di Swift ada kebutuhan untuk mengoptimalkan setiap proses karena kami biasanya menggunakan bahasa ini di sisi server.
Nicolas Manzini
25

Berikut ini sekering dari dua jawaban yang paling banyak dipilih dengan regex yang benar: ekstensi String menggunakan predikat sehingga Anda dapat memanggil string.isEmail

    extension String {
        var isEmail: Bool {
           let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,20}"            
           let emailTest  = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
           return emailTest.evaluateWithObject(self)
        }
    }
Nicolas Manzini
sumber
19

Cara termudah di Swift 5

extension String {
    var isValidEmail: Bool {
        NSPredicate(format: "SELF MATCHES %@", "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}").evaluate(with: self)
    }
}

Contoh

"[email protected]".isValidEmail

kembali ...

true
Ken Mueller
sumber
2
apa gunanya mengulangi jawaban yang diulang? yang tidak bergantung pada fitur Swift 5 apa pun
rommex
17

Saya sarankan menggunakannya sebagai ekstensi dari String:

extension String {    
    public var isEmail: Bool {
        let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)

        let firstMatch = dataDetector?.firstMatch(in: self, options: NSRegularExpression.MatchingOptions.reportCompletion, range: NSRange(location: 0, length: length))

        return (firstMatch?.range.location != NSNotFound && firstMatch?.url?.scheme == "mailto")
    }

    public var length: Int {
        return self.characters.count
    }
}

Dan untuk menggunakannya:

if "[email protected]".isEmail { // true
    print("Hold the Door")
}
JeffersonBe
sumber
1
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
Perbarui Swift 4: String ekstensi {public var isEmail: Bool {let dataDetector = coba? NSDataDetector (jenis: NSTextCheckingResult.CheckingType.link.rawValue) biarkan firstMatch = dataDetector? .FirstMatch (dalam: mandiri, opsi: NSRegularExpression.MatchingOptions.reportCompletion, kisaran: NSRange (lokasi: 0, panjang: hitung) kembali) range.location! = NSNotFound && firstMatch? .url? .scheme == "mailto")}
Duan Nguyen
15

Ini adalah versi terbaru untuk Swift 2.0 - 2.2

 var isEmail: Bool {
    do {
        let regex = try NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", options: .CaseInsensitive)
        return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil
    } catch {
        return false
    }
}
Joel García Verástica
sumber
8
foo @ bar mengembalikan benar ?!
Rémy Virin
2
memvalidasi aa @ aach to true
netshark1000
4
Itu karena RFC memvalidasi alamat email ini menjadi true;)
dulgan
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
itu benar-benar salah / buruk untuk tidak men-cache predikat. itu adalah hal pertama yang Apple katakan tentang masalah ini dalam dokumen. kesalahan mencolok yang dilakukan oleh sebagian besar jawaban di halaman.
Fattie
9

Ada banyak jawaban yang benar di sini, tetapi banyak dari "regex" tidak lengkap dan dapat terjadi bahwa email seperti: "name @ domain" menghasilkan email yang valid, tetapi ternyata tidak. Berikut solusi lengkapnya:

extension String {

    var isEmailValid: Bool {
        do {
            let regex = try NSRegularExpression(pattern: "(?:[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])+)\\])", options: .CaseInsensitive)
            return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil
        } catch {
            return false
        }
    }
}
Andrea.Ferrando
sumber
tidak berfungsi sebagaimana mestinya, ini memungkinkan Anda menambahkan spasi setelah domain.
Juan Boero
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
@Fattie membantah pernyataan Anda. Komentar Anda sangat tidak berguna, menyarankan peningkatan, mengusulkan perbaikan. Mengatakan sepenuhnya salah adalah sangat bodoh dan mendasari mentalitas yang erat
Andrea.Ferrando
"Ada banyak jawaban benar di sini" kalimat itu sangat salah :) :)
Fattie
8

Berikut adalah metode berdasarkan rangeOfString:

class func isValidEmail(testStr:String) -> Bool {
    let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let range = testStr.rangeOfString(emailRegEx, options:.RegularExpressionSearch)
    let result = range != nil ? true : false
    return result
}

Catatan: panjang TLD yang diperbarui.

Berikut adalah RegEx definitif untuk email sesuai RFC 5322, perhatikan bahwa ini paling baik tidak digunakan karena hanya memeriksa sintaksis dasar alamat email dan tidak memeriksa apakah domain tingkat atas ada.

(?: [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]) +)
     \])

Lihat Regular-Expressions.info untuk informasi lebih lengkap tentang email RegExs.

Perhatikan bahwa tidak ada yang lolos seperti yang disyaratkan oleh bahasa seperti Objective-C atau Swift.

zaph
sumber
1
emailRegEx yang Anda gunakan benar-benar salah. Itu hanya memungkinkan untuk TLD 2 hingga 4 karakter, sementara domain seperti .engineerada.
Antzi
Dipahami, saya tidak membela jawaban saya tetapi tingkat pengeditan. Tambahkan komentar seperti di atas, pilih-turun, arahkan ke jawaban yang lebih baik, tambahkan jawaban Anda sendiri. Tidak tepat untuk mengubah jawaban secara substansial. Saya telah menambahkan RegEx difusif untuk kelengkapan.
zaph
Kenapa oh mengapa tidak menghapus saja jawabannya? Apa alasan yang memungkinkan untuk menyimpannya di sini?
Fattie
7

Saya lebih suka menggunakan ekstensi untuk itu. Selain itu, url ini http://emailregex.com dapat membantu Anda menguji apakah regex benar. Bahkan, situs ini menawarkan implementasi differents untuk beberapa bahasa pemrograman. Saya membagikan implementasi saya untuk Swift 3 .

extension String {
    func validateEmail() -> Bool {
        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
        return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: self)
    }
}
Marlon Ruiz
sumber
ada beberapa masalah .. Anda dapat memiliki, misalnya .. bla @ .abc dengan titik aneh di sana
Fattie
5

Untuk swift 2.1: ini berfungsi dengan benar dengan email foo @ bar

extension String {
    func isValidEmail() -> Bool {
        do {
            let regex = try NSRegularExpression(pattern: "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}", options: .CaseInsensitive)
            return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, self.characters.count)) != nil
        } catch {
                return false
        }
    }
}
lee5783
sumber
1
Ini sepertinya bekerja dengan baik untuk saya. Sejauh yang saya mengerti Anda bahkan bisa menghilangkan 'AZ' (huruf kapital) karena Anda memiliki opsi .CaseInsensitive set tetap ...
AZOM
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
5

Penggunaan Swift 4.2

extension String {
    func isValidEmail() -> Bool {
        let regex = try? NSRegularExpression(pattern: "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$", options: .caseInsensitive)
        return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.count)) != nil
    }
    func isValidName() -> Bool{
        let regex = try? NSRegularExpression(pattern: "^[\\p{L}\\.]{2,30}(?: [\\p{L}\\.]{2,30}){0,2}$", options: .caseInsensitive)

        return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.count)) != nil
    } }

Dan digunakan

if (textField.text?.isValidEmail())! 
    {
      // bla bla
    }
else 
    {

    }
ikbal
sumber
4

Ini versi baru untuk "THE REASONABLE SOLUTION" oleh @Fattie, diuji pada Swift 4.1 dalam file baru bernama String+Email.swift:

import Foundation

extension String {
    private static let __firstpart = "[A-Z0-9a-z]([A-Z0-9a-z._%+-]{0,30}[A-Z0-9a-z])?"
    private static let __serverpart = "([A-Z0-9a-z]([A-Z0-9a-z-]{0,30}[A-Z0-9a-z])?\\.){1,5}"
    private static let __emailRegex = __firstpart + "@" + __serverpart + "[A-Za-z]{2,6}"

    public var isEmail: Bool {
        let predicate = NSPredicate(format: "SELF MATCHES %@", type(of:self).__emailRegex)
        return predicate.evaluate(with: self)
    }
}

Jadi penggunaannya sederhana:

let str = "[email protected]"
if str.isEmail {
    print("\(str) is a valid e-mail address")
} else {
    print("\(str) is not a valid e-mail address")
}

Aku hanya tidak ingin menambahkan funcke Stringobjek, sebagai alamat e-mail melekat kepada mereka (atau tidak). Jadi Boolproperti akan lebih cocok daripada func, dari pemahaman saya.

Alejandro Iván
sumber
2

Buat ekstensi sederhana:

extension NSRegularExpression {

    convenience init(pattern: String) {
        try! self.init(pattern: pattern, options: [])
    }
}

extension String {

    var isValidEmail: Bool {
        return isMatching(expression: NSRegularExpression(pattern: "^[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}$"))
    }

    //MARK: - Private

    private func isMatching(expression: NSRegularExpression) -> Bool {
        return expression.numberOfMatches(in: self, range: NSRange(location: 0, length: characters.count)) > 0
    }
}

Contoh:

"[email protected]".isValidEmail //true
"b@bb".isValidEmail //false

Anda dapat memperpanjang berikut ekstensi untuk apa pun yang Anda perlu: isValidPhoneNumber, isValidPassworddll ...

Bartłomiej Semańczyk
sumber
Perhatikan bahwa NSRangeproperti length harus digunakan String utf16.countsebagai ganticharacters.count
Leo Dabus
2

Di Swift 4.2 dan Xcode 10.1

//Email validation
func isValidEmail(email: String) -> Bool {
    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
    var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
    if valid {
        valid = !email.contains("Invalid email id")
    }
    return valid
}

//Use like this....
let emailTrimmedString = emailTF.text?.trimmingCharacters(in: .whitespaces)
if isValidEmail(email: emailTrimmedString!) == false {
   SharedClass.sharedInstance.alert(view: self, title: "", message: "Please enter valid email")
}

Jika Anda ingin menggunakan SharedClass.

//This is SharedClass
import UIKit
class SharedClass: NSObject {

static let sharedInstance = SharedClass()

//Email validation
func isValidEmail(email: String) -> Bool {
    let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
    var valid = NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: email)
    if valid {
        valid = !email.contains("Invalid email id")
    }
    return valid
}

private override init() {

}
}

Dan memanggil fungsi seperti ini ....

if SharedClass.sharedInstance. isValidEmail(email: emailTrimmedString!) == false {
   SharedClass.sharedInstance.alert(view: self, title: "", message: "Please enter correct email")
   //Your code here
} else {
   //Code here
}
iOS
sumber
1

Saya membuat perpustakaan yang dirancang untuk validasi input dan salah satu "modul" memungkinkan Anda untuk dengan mudah memvalidasi banyak hal ...

Misalnya untuk memvalidasi email:

let emailTrial = Trial.Email
let trial = emailTrial.trial()

if(trial(evidence: "[email protected]")) {
   //email is valid
}

SwiftCop adalah perpustakaan ... semoga membantu!

Andres
sumber
1

Berikut ini adalah ekstensi di Swift 3

extension String {
    func isValidEmail() -> Bool {
        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
        return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: self)
    }
}

Gunakan saja seperti ini:

if yourEmailString.isValidEmail() {
    //code for valid email address
} else {
    //code for not valid email address
}
Ikan Gefilte
sumber
Mengubah menggunakan Regex dari jawaban alexcristea, itu solusi sempurna.
ittgung
0

Karena ada begitu banyak nama domain aneh tingkat atas sekarang, saya berhenti memeriksa panjang domain teratas ...

Inilah yang saya gunakan:

extension String {

    func isEmail() -> Bool {
        let emailRegEx = "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$"
        return NSPredicate(format:"SELF MATCHES %@", emailRegEx).evaluateWithObject(self)
    } 
}
manusia salju10
sumber
0

Tampaknya bekerja juga ...

let regex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"

func validate(email: String) -> Bool {
    let matches = email.rangeOfString(regex, options: .RegularExpressionSearch)
    if let _ = matches {
        return true
    }
    return false
}
Logicopolis
sumber
0

Jawaban yang diperbarui @Arsonik menjawab Swift 2.2, menggunakan kode verbose lebih sedikit daripada solusi yang ditawarkan lainnya:

extension String {
    func isValidEmail() -> Bool {
        let regex = try? NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", options: .CaseInsensitive)
        return regex?.firstMatchInString(self, options: [], range: NSMakeRange(0, self.characters.count)) != nil
    }
}
Matias Seijas
sumber
abcd @ a lulus dengan regex ini. Anda harus memperbaikinya.
Gunhan
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
0

true@Jawaban JeffersonBe dekat, tetapi kembali jika stringnya adalah "sesuatu yang mengandung email seseorang yang [email protected]" yang bukan yang kita inginkan. Berikut ini adalah ekstensi pada String yang berfungsi dengan baik (dan memungkinkan pengujian untuk nomor telepon yang valid dan detektor data lainnya untuk boot.

/// Helper for various data detector matches.
/// Returns `true` iff the `String` matches the data detector type for the complete string.
func matchesDataDetector(type: NSTextCheckingResult.CheckingType, scheme: String? = nil) -> Bool {
    let dataDetector = try? NSDataDetector(types: type.rawValue)
    guard let firstMatch = dataDetector?.firstMatch(in: self, options: NSRegularExpression.MatchingOptions.reportCompletion, range: NSRange(location: 0, length: length)) else {
        return false
    }
    return firstMatch.range.location != NSNotFound
        // make sure the entire string is an email, not just contains an email
        && firstMatch.range.location == 0
        && firstMatch.range.length == length
        // make sure the link type matches if link scheme
        && (type != .link || scheme == nil || firstMatch.url?.scheme == scheme)
}
/// `true` iff the `String` is an email address in the proper form.
var isEmail: Bool {
    return matchesDataDetector(type: .link, scheme: "mailto")
}
/// `true` iff the `String` is a phone number in the proper form.
var isPhoneNumber: Bool {
    return matchesDataDetector(type: .phoneNumber)
}
/// number of characters in the `String` (required for above).
var length: Int {
    return self.characters.count
}
Gujamin
sumber
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
0

Dan untuk Swift 3 :

extension String {
    func isValidEmail() -> Bool {
        let regex = try? NSRegularExpression(pattern: "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$", options: .caseInsensitive)
        return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.characters.count)) != nil
    }
}
Danut Pralea
sumber
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
0

Satu-satunya tambahan saya ke daftar tanggapan adalah bahwa untuk Linux, NSRegularExpressiontidak ada, sebenarnyaRegularExpression

    func isEmail() -> Bool {

    let patternNormal = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"

    #if os(Linux)
        let regex = try? RegularExpression(pattern: patternNormal, options: .caseInsensitive)
    #else
        let regex = try? NSRegularExpression(pattern: patternNormal, options: .caseInsensitive)
    #endif

    return regex?.firstMatch(in: self, options: [], range: NSMakeRange(0, self.characters.count)) != nil

Ini berhasil dikompilasi di kedua macOS & Ubuntu.

Andrei Popa
sumber
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus
0

Solusi terbaik dengan hasil terbaik untuk

Swift 4.x

 extension String {

        func validateAsEmail() -> Bool {
            let emailRegEx = "(?:[a-zA-Z0-9!#$%\\&‘*+/=?\\^_`{|}~-]+(?:\\.[a-zA-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])+)\\])"

            let emailTest = NSPredicate(format:"SELF MATCHES[c] %@", emailRegEx)
            return emailTest.evaluate(with: self)
        }
    }
Abdelahad Darwish
sumber
0

Saya suka membuat ekstensi

   extension String {

func isValidateEmail() -> Bool {
    let emailFormat = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
    let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)
    return emailPredicate.evaluate(with: self)
}

}

pemakaian:

if emailid.text!.isValidateEmail() == false(){
 //do what ever you want if string is not matched.

}
siva kumar
sumber
0

Cepat 5

 func isValidEmailAddress(emailAddressString: String) -> Bool {

 var returnValue = true
 let emailRegEx = "[A-Z0-9a-z.-_]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,3}"

 do {
        let regex = try NSRegularExpression(pattern: emailRegEx)
        let nsString = emailAddressString as NSString
        let results = regex.matches(in: emailAddressString, range: NSRange(location: 0, length: nsString.length))

        if results.count == 0
        {
            returnValue = false
        }

    } catch let error as NSError {
        print("invalid regex: \(error.localizedDescription)")
        returnValue = false
    }

    return  returnValue
}

Kemudian:

let validEmail = isValidEmailAddress(emailAddressString: "[email protected]")
print(validEmail)
Arafin Russell
sumber
0

Regex sempurna seperti Google Email

"^[A-Z0-9a-z][a-zA-Z0-9_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
ami rt
sumber
2
siapa pun yang memilih jawaban saya, silakan periksa pengetahuan Anda. Saya telah menerapkan regex ini dalam banyak kode dan teman-teman saya menggunakan regex ini dan berfungsi dengan baik..Sebelum memilih jawaban saya, silakan lakukan komentar dan beri tahu saya apa yang salah dengan regex ini.
ami rt
Saya pikir saya bisa menjawab: Regex Anda sederhana dan tidak cocok dengan RFC. Misalnya, email dapat memiliki tanda kutip dan bahkan spasi di bagian pertama! Lihatlah haacked.com/archive/2007/08/21/…
Hugal31
1
Maaf, Saudaraku, saya pikir Anda harus memeriksa validasi email google, tidak ada cara untuk menambahkan Spasi di bagian pertama email, dan jika regex saya salah, mengapa tidak ada yang memposting tulisan dan menyempurnakan regex.
ami rt
Menurut RFC 5322, "Halo dunia!" @ Example.com adalah email yang valid. Memang, hampir tidak mungkin untuk membuat regex yang valid. Tidak semua penyedia email akan tetap menggunakan validasi email google.
Hugal31
1
Itulah yang ingin saya dengarkan, dan itulah sebabnya saya sebutkan dalam tajuk tebal bahwa regex di atas seperti Google. Terima kasih
ami rt
-1

Atau Anda dapat memiliki ekstensi untuk teks opsional UITextField:

Cara Penggunaan:

if  emailTextField.text.isEmailValid() {
      print("email is valid")
}else{
      print("wrong email address")
}

perpanjangan:

extension Optional where Wrapped == String {
    func isEmailValid() -> Bool{
        guard let email = self else { return false }
        let emailPattern = "[A-Za-z-0-9.-_]+@[A-Za-z0-9]+\\.[A-Za-z]{2,3}"
        do{
            let regex = try NSRegularExpression(pattern: emailPattern, options: .caseInsensitive)
            let foundPatters = regex.numberOfMatches(in: email, options: .anchored, range: NSRange(location: 0, length: email.count))
            if foundPatters > 0 {
                return true
            }
        }catch{
            //error
        }
        return false
    }
}
Maciej Chrzastek
sumber
Perhatikan bahwa properti panjang NSRange harus menggunakan String utf16.count alih-alih karakter.count
Leo Dabus