Reputation: 5765
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
Reputation: 2345
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 #"..."#
:
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
}
}
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
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