Как проверить адрес электронной почты в swift?

255

Кто-нибудь знает, как проверить адрес электронной почты в Swift? Я нашел этот код:

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

но я не могу перевести его в Swift.

  • 6
    перевод должен быть простым. какая часть доставляет вам проблемы?
  • 0
    Проблема заключалась в следующем: «NSRegularExpression * regEx = [[NSRegularExpression alloc] initWithPattern: regExPattern options: NSRegularExpressionCaseInsensitive error: nil];»
Показать ещё 6 комментариев
Теги:
validation
email

33 ответа

668
Лучший ответ

Я бы использовал NSPredicate:

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

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

для версий Swift более ранних, чем 3.0:

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

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

для версий Swift ранее 1.2:

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

    if let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) {
        return emailTest.evaluateWithObject(testStr)
    }
    return false
}
  • 0
    Это работает, спасибо!
  • 5
    не return emailTest.evaluateWithObject(testStr) намного проще и удобочитаемее? Сравнение с == true немного похоже на Javascript.
Показать ещё 18 комментариев
100

Как расширение класса String

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

использование

if "rdfsdsfsdfsd".isValidEmail() {

}
  • 4
    countElements теперь count
  • 3
    Это должен быть принятый ответ.
Показать ещё 9 комментариев
89

Редактирование, обновленное для 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)

}

Оригинальный ответ для 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)

}

Он отлично работает.

  • 2
    первый с действительным регулярным выражением. другие подтверждают, что aa @ aach верна
  • 8
    Это должен быть главный ответ. Не то чтобы с неправильным регулярным выражением
Показать ещё 7 комментариев
39

Если вы ищете чистое и простое решение для этого, вы должны взглянуть на https://github.com/nsagora/validation-components.

Он содержит предикат проверки электронной почты, который легко интегрируется в ваш код:

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

За капотом используется 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])+)\\])"
  • 3
    Вау, не знал о emailregex.com. Это превосходно!
  • 2
    Наконец, тот, который фильтрует электронную почту. @. Email.com
Показать ещё 4 комментария
23

Вот предохранитель двух наиболее голосовых ответов с правильным регулярным выражением: расширение строки с использованием предиката, чтобы вы могли вызвать 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)
        }
    }
  • 0
    Этот даже не близок к тому, чтобы быть правильным.
18

Вот разумное решение:

"РАЗУМНОЕ РЕШЕНИЕ"

Используется и проверяется годами во многих приложениях огромного объема.

1 - это позволяет избежать многих очень регулярных ошибок, которые вы часто видите в этих предложениях

2 - он не допускает глупых писем, таких как "x @x", которые технически действительны, но совершенно глупы - и ваш персонал поддержки, и т.д., В любом случае немедленно отклонил бы. Если вам нужно решение, которое позволяет глупые электронные письма, используйте другое решение.

3 - это чрезвычайно понятно

4 - это KISS, надежный и проверенный на разрушение в коммерческих приложениях с огромным количеством пользователей

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

Объяснение:

В последующем описании "OC" означает обычный символ: так, буква или цифра.

__firstpart... должен начинаться и заканчиваться OC. Для символов в середине у вас может быть несколько необычных символов, таких как подчеркивание, но начало и конец должны быть OC. (Можно иметь только один OC, например, [email protected])

__serverpart... У вас есть такие разделы, как "бла". которые повторяют. (Так, тип mail.city.fcu.edu.) Секции должны начинаться и заканчиваться OC, но в середине вы также можете иметь тире "-". (Если вы хотите, чтобы там присутствовали другие необычные символы, скажем, подчеркивание, просто добавьте их перед чертой.) Хорошо иметь раздел, который является только одним OC. (Как в [email protected]) Вы можете иметь до пяти разделов; Вы должны иметь один. Наконец, размер TLD (например,.com) строго от 2 до 8.

Обратите внимание, что вы просто сохраняете предикат как глобальный (тривиальный в Swift), нет необходимости каждый раз создавать его.

Это первое, что Apple упоминает о проблеме в документе.

Любые решения, которые вы видите, которые не используют глобальный подход, абсолютно неверны.

  • 1
    Поддерживает ли он новые TLD, такие как .engineer?
  • 0
    Привет @Roman - обратите внимание, где четко сказано: «Наконец, TLD (.com или тому подобное) строго от 2 до 8 букв». Это позаботится об этом. Вы можете изменить «8» на значение, которое вы предпочитаете. (В настоящее время во многих крупных компаниях служба поддержки клиентов просто отвергает любые длинные ДВУ как мошенничество, но в любом случае это ваше решение, используйте «8» или любое значение, которое вам нравится.)
Показать ещё 5 комментариев
15

Это обновленная версия для 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
    }
}
  • 8
    foo @ bar возвращает true ?!
  • 2
    проверяет aa @ aach на true
Показать ещё 3 комментария
14

Я бы предложил использовать его как расширение строки:

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

И использовать это:

if "[email protected]".isEmail { // true
    print("Hold the Door")
}
  • 7
    хаха держи дверь!
  • 1
    Обратите внимание, что свойство длины NSRange должно использовать String utf16.count вместо characters.count.
Показать ещё 1 комментарий
8

Вот метод, основанный на 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
}

Примечание: обновлена длина TLD.

Вот окончательный RegEx для электронной почты согласно RFC 5322, обратите внимание, что это лучше не использовать, потому что он только проверяет основной синтаксис адресов электронной почты и не проверяет, существует ли домен верхнего уровня.

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

Смотрите Regular-Expressions.info для более полной информации по электронной почте RegExs.

Обратите внимание, что экранирование не требуется, как того требует язык, такой как Objective-C или Swift.

  • 1
    emailRegEx, который вы используете, просто неверен. .engineer доменов .engineer длиной от 2 до 4 символов, в то время как существуют домены, подобные .engineer .
  • 0
    Понял, я не защищаю свой ответ, но уровень редактирования. Добавьте комментарий, как указано выше, проголосуйте вниз, укажите лучший ответ, добавьте свой собственный ответ. Не стоит существенно менять ответ. Я добавил диффузный RegEx для полноты.
Показать ещё 1 комментарий
7

Я предпочитаю использовать для этого расширение. Кроме того, этот url http://emailregex.com может помочь вам проверить правильность регулярного выражения. Фактически, сайт предлагает различные реализации для некоторых языков программирования. Я разделяю свою реализацию для 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)
    }
}
  • 0
    есть несколько проблем .. у вас может быть, например .. бла @ .abc со странной точкой там
6

Здесь есть много правильных ответов, но многие из "регулярных выражений" являются неполными, и может случиться так, что электронное письмо вроде: "name @domain" приводит к действительной электронной почте, но это не так. Здесь полное решение:

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
        }
    }
}
  • 0
    не работает должным образом, он позволяет добавлять пробелы после домена.
  • 0
    Обратите внимание, что свойство длины NSRange должно использовать String utf16.count вместо characters.count.
Показать ещё 2 комментария
5

Для быстрого 2.1: это работает правильно с адресом электронной почты 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
        }
    }
}
  • 1
    Это, кажется, работает хорошо для меня. Насколько я понимаю, вы могли бы даже опустить 'AZ' (заглавные буквы), так как у вас все равно есть опция .CaseInsensitive ...
  • 0
    @AZOM: Да, правильно
Показать ещё 1 комментарий
2

Использование 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
    } }

И использовал

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

    }
2

Создать простое расширение:

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

Пример:

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

Вы можете расширить следующее расширение до всего, что вам нужно: isValidPhoneNumber, isValidPassword и т.д.

  • 0
    Очень Свифт! Благодарю.
  • 0
    Обратите внимание, что NSRange длины NSRange должно использовать String utf16.count вместо characters.count
2

Я создал библиотеку, предназначенную для проверки ввода, и один из "модулей" позволяет легко проверять кучу вещей...

Например, чтобы проверить электронную почту:

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

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

SwiftCop - это библиотека... надеюсь, что это поможет!

1

В Swift 4.2 и 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")
}

Если вы хотите использовать 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() {

}
}

И вызвать функцию, как это....

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

Это новая версия " РАЗУМНОГО РЕШЕНИЯ" от @Fattie, протестированная на Swift 4.1 в новом файле с именем 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)
    }
}

Поэтому его использование простое:

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

Я просто не люблю добавлять func к объектам String, поскольку им присваивается адрес электронной почты (или нет). Так что, насколько я понимаю, свойство Bool подходит лучше, чем func.

1

Кажется, тоже работает...

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

Вот очень простой способ, доступный в текущем Swiftmailer. Большинство других ответов старые и заново изобретают колесо.

Согласно документации Swiftmailer: https://swiftmailer.symfony.com/docs/messages.html#quick-reference

use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\RFCValidation;

$validator = new EmailValidator();
$validator->isValid("[email protected]", new RFCValidation()); //true

Это, безусловно, самый простой и надежный подход, IMO. Просто установите через Composer библиотеку Egulias\EmailValidator, которая все равно должна быть включена как зависимость от SwiftMailer.

0

Я улучшил ответ @Azik. Я допускаю больше специальных символов, которые разрешены руководящими принципами, а также возвращаю несколько дополнительных крайних случаев как недействительные.

Группа думает, что здесь разрешено только ._%+- в локальной части не правильно в соответствии с руководящими принципами. Смотрите ответ @Anton Gogolev на этот вопрос или смотрите ниже:

Локальная часть адреса электронной почты может использовать любой из этих символов ASCII:

  • прописные и строчные буквы латинского алфавита до A Z и к a z;

  • цифры от 0 до 9;

  • специальные символы !#$%&'*+-/=?^_'{|}~;

  • точка . при условии, что это не первый или последний символ, если он не указан в кавычках, а также при условии, что он не появляется последовательно, если не [email protected] кавычки (например, [email protected] не допускается, но "John..Doe"@example.com is позволил);

  • пробел и символы "(),:;<>@[\] допускаются с ограничениями (они допускаются только внутри строки в кавычках, как описано в приведенном ниже абзаце, и, кроме того, перед косой чертой или двойной кавычкой должен стоять обратная косая черта); комментарии разрешены

  • с круглыми скобками в любом конце локальной части; например, john.smith(comment)@example.com и (comment)[email protected] оба эквивалентны [email protected];

Код, который я использую, не позволяет использовать специальные символы с ограниченным доступом, но предоставляет гораздо больше возможностей, чем большинство ответов здесь. Я бы предпочел более мягкую проверку ошибкам со стороны предостережения.

if enteredText.contains("..") || enteredText.contains("@@") 
   || enteredText.hasPrefix(".") || enteredText.hasSuffix(".con"){
       return false
}

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: enteredText)
0

Мне нравится создавать расширение

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

}

использование:

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

}
0

Лучшее решение с лучшим результатом для

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)
        }
    }
0
//Email validation
func validateEmail(enterEmail: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:enterEmail)
}

100% работает и проверено

  • 1
    не удалось, если вы напишите ".com" дважды в конце. Проверьте, по крайней мере, очень распространенные случаи, прежде чем упомянуть 100% работающих и проверенных
0

Или вы можете иметь расширение для дополнительного текста UITextField:

как использовать:

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

расширение:

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
    }
}
  • 0
    Обратите внимание, что свойство длины NSRange должно использовать String utf16.count вместо characters.count.
0

Вот расширение в 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)
    }
}

Просто используйте его так:

if yourEmailString.isValidEmail() {
    //code for valid email address
} else {
    //code for not valid email address
}
  • 0
    Переход на использование ответа Regex от alexcristea - это идеальное решение.
0

Основные NSRegularExpression, Swift 3, посмотрите сами с помощью IBM Swift Sandbox Link:

let pattern = "[^@]+@[a-zA-Z0-9-.]+\\.[a-zA-Z]{2,}"

var regex: NSRegularExpression?
do {
    regex = try NSRegularExpression(pattern: pattern, options: [])
} catch let error {
    print("regex failed for \(pattern), error \(error)")
}

let testEmail = "[email protected]"

let matches = regex!.matches(in: testEmail, options: .withTransparentBounds, range: NSMakeRange(0, testEmail.characters.count))

if matches.count != 0 {
    print("Email appears to be valid")
} else {
    print("Email does not appear to be valid")
}

IBM Sandbox: Базовая Swift NSRegularExpression Проверка электронной почты

0

Мое единственное дополнение к списку ответов было бы то, что для Linux NSRegularExpression не существует, на самом деле RegularExpression

    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

Это успешно компилируется как для macOS, так и для Ubuntu.

  • 0
    Обратите внимание, что свойство длины NSRange должно использовать String utf16.count вместо characters.count.
0

И для 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
    }
}
  • 0
    Обратите внимание, что свойство длины NSRange должно использовать String utf16.count вместо characters.count.
0
Ответ на

@JeffersonBe близок, но возвращает true, если строка "something with [email protected] действительная электронная почта", которая не является тем, что мы хотим. Ниже приведено расширение на String, которое хорошо работает (и позволяет тестировать действительный номер телефона и другие детекторы данных для загрузки.

/// 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
}
  • 0
    Обратите внимание, что свойство длины NSRange должно использовать String utf16.count вместо characters.count.
0

Обновленный ответ @Arsonik ответит на Swift 2.2, используя менее подробный код, чем другие предлагаемые решения:

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
    }
}
  • 0
    abcd @ a проходит с этим регулярным выражением. Вы должны это исправить.
  • 0
    Обратите внимание, что свойство длины NSRange должно использовать String utf16.count вместо characters.count.
0

Поскольку в настоящее время существует так много странных доменных имен верхнего уровня, я перестаю проверять длину верхнего домена...

Вот что я использую:

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)
    } 
}
  • 0
    совершенно неправильно
-2

Вы можете найти полезную фреймворк повторно используемой формы. Он создал свои правила поля, и вы создаете свои собственные правила проверки, применяя протокол FieldValidator.

Пример ниже: импортировать UIKit import FormValidationKit

класс ViewController: UIViewController, FormValidationDelegate, FieldValidatorDelegate {   var formValidator: FormValidator?

var usernameValidator : FieldValidator?
var emailValidator : FieldValidator?

@IBOutlet weak var usernameTf: UITextField!
@IBOutlet weak var emailTf: UITextField!

@IBAction func didTapButton(sender: AnyObject) {

    formValidator?.submit()
}

override func viewDidLoad() {
    super.viewDidLoad()
    //Initialize the form validator
    formValidator = FormValidator()

    //Create field validators
    //Set nil to first field validator
    usernameValidator = FieldValidator(inputValue: { () -> AnyObject in
        return self.usernameTf.text
    }, rules: [Required(validationError: ValidationError(hint: "Field is required"))], nextValidator: nil, form: formValidator!)
    usernameValidator!.delegate = self


    emailValidator = FieldValidator(inputValue: { () -> AnyObject in
        return self.emailTf.text
    }, rules: [Email(validationError: ValidationError(hint: "Proper email format"))], nextValidator: usernameValidator!, form: formValidator!)
    emailValidator!.delegate = self

    formValidator?.initialValidator = emailValidator!
    formValidator?.delegate = self
}

//per field error delegate method
func didEvaluateField(field: FieldValidator, errors: Array<String>, form: FormValidator) {
    switch field {
    case usernameValidator!:
        println("Username field error")
        break;
    case emailValidator!:
        println("Username field error")
    default:
        println("Field error")
    }
}

//form delegate methods
func didPassFormValidation(form: FormValidation) {
    println(__FUNCTION__)
}

func didFailFormValidation(form: FormValidation) {
    println(__FUNCTION__)
}

ссылка Github здесь

-3

Идеальное регулярное выражение, например Google Email

"^[A-Z0-9a-z][a-zA-Z0-9_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
  • 0
    кто бы ни проголосовал за мой ответ, пожалуйста, проверьте свои знания. Я применил это регулярное выражение во многих кодах, и мои друзья используют это регулярное выражение, и оно прекрасно работает. Перед тем как проголосовать за мой ответ, пожалуйста, прокомментируйте и дайте мне знать, что не так с этим регулярным выражением.
  • 0
    Я думаю, что могу ответить: ваше регулярное выражение простое и не соответствует RFC. Например, электронные письма могут содержать кавычки и даже пробелы в первой части! Посмотрите на haacked.com/archive/2007/08/21/…
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню