headkit
headkit

Reputation: 3327

How to check if a string only contains numbers in Swift 2?

Before Swift 2 I used this extension to check if a string only is made out of numbers:

func isNumbersOnly() -> Bool {
        let regexNumbersOnly = NSRegularExpression(pattern: ".*[^0-9].*", options: nil, error: nil)!
        return regexNumbersOnly.firstMatchInString(self, options: nil, range: NSMakeRange(0, self.length())) != nil
}

but now with Swift 2 I get the error

Cannot invoke initializer for type 'NSRegularExpression' with an argument list of type '(pattern: String, options: NilLiteralConvertible, error: NilLiteralConvertible)'

Is there a better known way now? Thnx!

Upvotes: 1

Views: 3691

Answers (3)

Clay Ellis
Clay Ellis

Reputation: 5330

Instead of using regular expressions, you can use CharacterSets to check for the existence (or absence) of certain characters. To check if the string is only digits you can use the following:

extension String {
    var isDigits: Bool {
        if isEmpty { return false }
        // The inverted set of .decimalDigits is every character minus digits
        let nonDigits = CharacterSet.decimalDigits.inverted
        return rangeOfCharacter(from: nonDigits) == nil
    }
}

This method can be applied to any type of CharacterSet and, in my opinion, is a lot cleaner than using regex strings.

Upvotes: 2

Eric Aya
Eric Aya

Reputation: 70098

In Swift 2 NSRegularExpression "throws" so you have to use it with try.

Also you can't pass nil for options anymore: if you don't want to specify options, pass an empty array (same for firstMatchInString).

And self.length() should become self.characters.count.

Last note: if the goal is to determine if a String contains only numbers, and since you're naming it "isNumbersOnly", the resulting Boolean should be true if there's only numbers: it's currently the inverse. I've fixed this in my example.

Ignoring errors:

let regexNumbersOnly = try! NSRegularExpression(pattern: ".*[^0-9].*", options: [])
return regexNumbersOnly.firstMatchInString(self, options: [], range: NSMakeRange(0, self.characters.count)) == nil

With proper error handling:

do {
    let regexNumbersOnly = try NSRegularExpression(pattern: ".*[^0-9].*", options: [])
    return regexNumbersOnly.firstMatchInString(self, options: [], range: NSMakeRange(0, self.characters.count)) == nil
} catch let error as NSError {
    print(error.description)
}

Upvotes: 2

Tommy
Tommy

Reputation: 100622

Swift 2 has adjusted the error-handling process; you should now try the call, not specifying an error and be prepared to catch an exception.

E.g.

do {
    let regexNumbersOnly = try NSRegularExpression(pattern: ..., options: nil)
    ... etc ...
} catch _ {}

... given that you're electing not to handle error states.

Upvotes: 1

Related Questions