MLyck
MLyck

Reputation: 5765

Swift regular expression format?

I'm familiar with doing pcre regexes, however they don't seem to work in swift.

^([1-9]\d{0,2}(\,\d{3})*|([1-9]\d*))(\.\d{2})?$

to validate numbers like 1,000,000.00

However, putting this in my swift function, causes an error.

    extension String {
    func isValidNumber() -> Bool {
        let regex = NSRegularExpression(pattern: "^([1-9]\d{0,2}(\,\d{3})*|([1-9]\d*))(\.\d{2})?$", options: .CaseInsensitive, error: nil)
        return regex?.firstMatchInString(self, options: nil, range: NSMakeRange(0, countElements(self))) != nil
    }
}

"Invalid escape sequence in litteral"

This is of course, because pcre uses the "\" character, which swift interprets as an escape (I believe?)

So since I can't just use the regexes I'm used to. How do I translate them to be compatible with Swift code?

Upvotes: 22

Views: 14670

Answers (2)

Manabu Nakazawa
Manabu Nakazawa

Reputation: 2345

Edit (June 2022)

From Swift 5.7, which you can use on Xcode 14.0 Beta 1 or later, you can use /.../ like this:

// Regex type
let regex = /^([1-9]\d{0,2}(\,\d{3})*|([1-9]\d*))(\.\d{2})?$/

Edit (Dec 2022): Since this internally creates Regex introduced in iOS 16 and macOS 13, the minimum deployment target must cover that OS version.

Advantages over #"..."#:

  • Your regex pattern is parsed at the compile-time, so you don't need to worry if your pattern is valid or not once your program is compiled
  • If your pattern is invalid, the compiler lets you know specifically which part is invalid as the compile error
  • Syntax highlighting is applied

So your code would look like this:

extension String {
    func isValidNumber() -> Bool {
        let regex = /^([1-9]\d{0,2}(\,\d{3})*|([1-9]\d*))(\.\d{2})?$/
            .ignoresCase()
        return (try? regex.firstMatch(in: self)) != nil
    }
}

Original answer

Since Swift 5, you can use #"..."# like this, so that you don't need to add extra escape sequences for Swift:

#"^([1-9]\d{0,2}(\,\d{3})*|([1-9]\d*))(\.\d{2})?$"#

Upvotes: 8

Avinash Raj
Avinash Raj

Reputation: 174696

Within double quotes, a single backslash would be readed as an escape sequence. You need to escape all the backslashes one more time in-order to consider it as a regex backslash character.

"^([1-9]\\d{0,2}(,\\d{3})*|([1-9]\\d*))(\\.\\d{2})?$" 

Upvotes: 39

Related Questions