Some of the methods in Swift that use regular expressions

  • 2020-05-09 19:22:40
  • OfStack

I've been using Swift for a while, but the most frustrating thing is that it doesn't yet support regular expressions.

First of all, this is a new language and I have a comment on the website a radar (rdar://17257306 for Apple folks). If you agree with this one, please support it.

By regular expressions I mean this (Ruby code):
 


if name =~ /ski$/
 puts "#{name} is probably polish"
end

If you want a quick query, you can use the =~ operator to return the matching result. In addition, you can use the /pattern/syntax form to directly use the regex.


 
url_pattern = /^https?:\/\/.*/


This is much better than using \\ to escape (which is common in regularization). If strings are used in regularization, it looks terrible.
 

NSRegularExpression *regex = [NSRegularExpression
  regularExpressionWithPattern:@"\\s+\\w{4,10}\\s\\d+"
                       options:0
                         error:nil];

Escaping each \ symbol makes the code less readable.   not to mention the creation of additional classes. Of course, if you need more powerful regularization capabilities, you'll have to develop a full set of specific implementation classes.

How does Swift work?

Swift currently does not provide a syntax or class to support regular, so it can only be implemented using the previously mentioned NSRegularExpression.

However, we can consider using swift's powerful operator for this. Consider the following scenario:
 


class Regex {
  let internalExpression: NSRegularExpression
  let pattern: String
 
  init(_ pattern: String) {
    self.pattern = pattern
    var error: NSError?
    self.internalExpression = NSRegularExpression(pattern: pattern, options: .CaseInsensitive, error: &error)
  }
 
  func test(input: String) -> Bool {
    let matches = self.internalExpression.matchesInString(input, options: nil, range:NSMakeRange(0, countElements(input)))
    return matches.count > 0
  }
}

This requires a lot of hypothesis testing when using NSRegularExpression. It would be much easier to use another method:

 


if Regex("\\w{4}").test("ABCD") {
  println("matches pattern")
}

We still have to use string escape, but it's much better than using native NSRegularExpression.

= ~ operator

After studying the method of Step Christopher for 1, I want to modify the operator function for 1. It seems quite simple:
 


operator infix =~ {}

This defines the location of the operator, just as when you operate on two elements, you do not put them in between, but before or after one element (as in the ++ operation). Here is a definition of a function that USES this operator:

 


func =~ (input: String, pattern: String) -> Bool {
  return Regex(pattern).test(input)
}

The complex parts are out there, and we simply call them.

Finally, the test results using regex are as follows:

 


let phoneNumber = "(800) 555-1111"
if phoneNumber =~ "(?\\d{3})?\\s\\d{3}-\\d{4}" {
  println("That looks like a valid US phone number")
}

I think this is a good result, and if Apple discovers the syntax of my regular implementation /regex/literal syntax one day, I'll be happy to support it.

update

1 helpful Hacker News critic   points out that 1 is closer to the direction I want, but using the existing API:
 


if let match = name.rangeOfString("ski$", options: .RegularExpressionSearch) {
  println("\(name) is probably polish")
}

Sure, I didn't know that, and it seems very useful.


Related articles: