2015-06-15 14 views
28

Napisałem tę funkcję w rozszerzeniu ciągu i nie mogę znaleźć błędu.Połączenie może zostać wywołane, ale nie jest oznaczone "spróbuj", a błąd nie jest obsługiwany: NSRegularExpression

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

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

Błąd jest:

Call can throw, but it is not marked with 'try' and the error is not handled

Odpowiedz

55

NSRegularExpression(pattern:) zgłasza błąd, jeśli wzór jest nieprawidłowy. W twoim przypadku wzór jest ustalony, więc nieprawidłowy wzór byłby błędem programowania .

Jest to use-case na „przymusowe-try” wyraz z try!:

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

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

try! wyłącza propagacji błędu więc nie że metoda nie wygeneruje błąd (co rozmówca ma do połowu). Spowoduje to przerwanie z wyjątkiem wykonawczym , jeśli wzorzec jest nieprawidłowy, co pomaga wcześnie wykryć błędy programowania .

Należy również zauważyć, że NSRange() zlicza długość NSString, to liczba punktów UTF-16 kodu, tak characters.count należy utf16.count, w przeciwnym razie może ulec awarii np ze znakami Emoji.

+0

http://emailregex.com/ wskazują nieco inny deseń - '[A-Z Z0-9a ._% + -] + @ [A-Za-Z0-9 .-] + \\ . [A-Za-z] {2,6} 'specjalnie dla Swifta. Co myślisz? – Michal

+0

@Michal: Powyższy kod używa '. Opcja CaseInsensitive' dla dopasowywania bez rozróżniania wielkości liter, a twój wzór pozwala na pisanie wielkich i małych liter. Wynik jest taki sam. –

+0

dodatkowy plus za wskazanie przypadku emoji! – Kubba

13

To dlatego, że inicjator może teraz wyjątek, więc trzeba try nazwać i być przygotowanym do catch wyjątku. Możesz to zrobić, dodając try przed inicjalizatorem i opisując swoją metodę za pomocą throws.

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

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

Potem, gdy chcesz wywołać metodę, to zrobić z poziomu do bloku i złapać błąd, który wychodzi.

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

Uwaga: Ja również zaktualizowane wezwanie regex.firstMatchInString aby odzwierciedlić fakt, że parametr options nie może przyjmować wartość zero.

3

Jeśli nie podoba try haczyk:

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

check ciąg jest prawidłowy format wiadomości:

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

można użyć string.rangeOfString i określ opcję .RegularExpressionSearch. To proste.

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

czy mógłbyś edytować swoje rozwiązanie z nieco bardziej szczegółami? – Whitefret

+0

Otrzymuję następujący błąd, gdy próbuję tego w swift 3: ** pogrubienie ** 'wykonanie nie powiodło się: błąd: Patterns.playground: 2: 12: błąd: wartość typu 'String' nie ma członka 'rangeOfString' e-mail zwrotny .rangeOfString ("^ [A-Z0-9a-z ._% + -] + @ [A-Za-z0-9 .-] + \\. [A-Za-z] {2,6} $" , opcje: .RegularExpressionSearch)! = zero'. Musi istnieć rozszerzenie String, którego używasz, które nie jest domyślnie włączone. –

Powiązane problemy