In Swift, what is a simple way to see if a string matches a pattern?
Pseudocode examples:
if string matches pattern ... if string =~ pattern ...
(I have read the Swift docs and haven't seen a regex capability. I've read about adding a new =~
operator which is a good idea yet more complex than I'd like because this is for a teaching project. I have tried rangeOfString
but get the error: 'String' does not have a member 'rangeOfString'. I am looking for a Swift solution, i.e. not typing NSRegularExpression. I do not need to do anything with the match result data.)
To check if a String matches a Pattern one should perform the following steps: Compile a String regular expression to a Pattern, using compile(String regex) API method of Pattern. Use matcher(CharSequence input) API method of Pattern to create a Matcher that will match the given String input against this pattern.
A regex pattern matches a target string. The pattern is composed of a sequence of atoms. An atom is a single point within the regex pattern which it tries to match to the target string. The simplest atom is a literal, but grouping parts of the pattern to match an atom will require using ( ) as metacharacters.
Most characters, including all letters ( a-z and A-Z ) and digits ( 0-9 ), match itself. For example, the regex x matches substring "x" ; z matches "z" ; and 9 matches "9" . Non-alphanumeric characters without special meaning in regex also matches itself. For example, = matches "=" ; @ matches "@" .
If the pattern matches the specified string, the method returns a Range<String.Index> object. Therefore, checking for a non- nil value tells us whether or not a match occurred.
But in Swift, you have to go through the trouble of initializing an NSRegularExpression object and converting back and forth from String ranges to NSRange values. It’s a total drag. Here’s the good news: You don’t need NSRegularExpression to use regular expressions in Swift.
In Swift, there are two basic kinds of patterns: those that successfully match any kind of value, and those that may fail to match a specified value at runtime. The first kind of pattern is used for destructuring values in simple variable, constant, and optional bindings.
Specifically, you’ll need to use NSRegularExpression if you want to match a pattern more than once in a string or extract values from capture groups. A regular expression can match its pattern one or more times on a string.
Swift version 3 solution:
if string.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil ...
Swift version 2 solution:
if string.rangeOfString(pattern, options: .RegularExpressionSearch) != nil ...
Example -- does this string contain two letter "o" characters?
"hello world".rangeOfString("o.*o", options: .RegularExpressionSearch) != nil
Note: If you get the error message 'String' does not have a member 'rangeOfString'
, then add this before: import Foundation
. This is because Foundation provides the NSString methods that are automatically bridged to the Swift String class.
import Foundation
Thanks to Onno Eberhard for the Swift 3 update.
The solutions mentioned above didn't work for me anymore, so I'm posting my solution here (I used an extension for String):
extension String { func matches(_ regex: String) -> Bool { return self.range(of: regex, options: .regularExpression, range: nil, locale: nil) != nil } }
Example:
if str.matches("^[a-zA-Z0-9._-]{1,30}$") { //... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With