web-dev-qa-db-fra.com

L'appel peut lancer, mais il n'est pas marqué avec 'try' et l'erreur n'est pas traitée: NSRegularExpression

J'ai écrit cette fonction dans l'extension de chaîne et je ne peux pas comprendre l'erreur.

func isEmail() -> Bool {
    let regex = NSRegularExpression(pattern: "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$", options: [.CaseInsensitive])

    return regex.firstMatchInString(self, options: nil, range: NSMakeRange(0, characters.count)) != nil
}

L'erreur est:

L'appel peut être lancé, mais il n'est pas marqué avec 'try' et l'erreur n'est pas gérée

28
Sahil Kapoor

NSRegularExpression(pattern:) renvoie une erreur si le modèle n'est pas valide. Dans votre cas, le motif est fixed, donc un motif invalide .__ serait une erreur de programmation.

Ceci est un cas d'utilisation pour l'expression "forcé-essayer" avec try!:

extension String {
    func isEmail() -> Bool {
        let regex = try! NSRegularExpression(pattern: "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$",
            options: [.CaseInsensitive])

        return regex.firstMatchInString(self, options:[],
            range: NSMakeRange(0, utf16.count)) != nil
    }
}

try! désactive la propagation d'erreur de sorte que la méthode n'envoie pas d'erreur (que l'appelant doit intercepter). Il abandonnera avec une exception d'exécution Si le modèle est invalide, ce qui permet de détecter rapidement les erreurs de programmation

Notez également que NSRange() compte la longueur de NSString, c’est-à-dire le nombre de points de code UTF-16, de sorte que characters.count devrait être utf16.count, sinon il pourrait planter E.g. avec des personnages Emoji.

55
Martin R

En effet, cet initialiseur peut maintenant générer une exception. Vous devez donc try pour l'appeler et être prêt à catch l'exception. Vous pouvez le faire en ajoutant try avant l'initialiseur et en annotant votre méthode avec throws.

extension String {
    func isEmail() throws -> Bool {
        let regex = try NSRegularExpression(pattern: "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$", options: [.CaseInsensitive])

        return regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, characters.count)) != nil
    }
}

Ensuite, lorsque vous souhaitez appeler la méthode, faites-la à partir d'un bloc do et interceptez l'erreur qui se produit.

do {
    try "[email protected]".isEmail()
} catch {
    print(error)
}

Remarque: j'ai également mis à jour votre appel regex.firstMatchInString afin de refléter le fait que le paramètre options ne peut plus prendre une valeur nulle.

13
Mick MacCallum

Si vous n'aimez pas essayer attraper:

extension String {
    func matchPattern(patStr:String)->Bool {
            var isMatch:Bool = false
            do {
                let regex = try NSRegularExpression(pattern: patStr, options: [.CaseInsensitive])
                let result = regex.firstMatchInString(self, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, characters.count))

                if (result != nil)
                {
                    isMatch = true
                }
            }
            catch {
                isMatch = false
            }
            return isMatch
    }
}    

vérifier que la chaîne est au format correct:

let emailInput:String = "[email protected]"
if (emailInput.matchPattern("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$"))
{
     print("this is e-mail!")
}
3
Chris Ho

Vous pouvez utiliser string.rangeOfString et spécifier l'option .RegularExpressionSearch. C'est simple.

func isEmail(email: String) -> Bool {
    return email.rangeOfString("^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$", options: .RegularExpressionSearch) != nil
}
1
solos