Regular Expressions in Swift

Brainstorming a bit, compile-time recognition and validation of regular expressions could also weave into the type system in really unique ways. For example, if the compiler knows how many capture groups a regex has, its match method could return a tuple with exactly that many elements, making destructuring a breeze:

let re = /(\d{4})-(\d{2})-(\d{2})/
print(type(of: re))  // "Regex<(String, String, String)>" 🤷🏻‍♂️

if let (year, month, day) = re.match("2020-03-09") {
  // do something with the match
} else {
  // no match
}

It could even parse named capture groups as tuple labels, if you wanted something a little more formal to pass around:

let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
print(type(of: re))  // "Regex<(year: String, month: String, day: String)>" 🤷🏻‍♂️

if let match = re.match("2020-03-09") {
  print(match.year, match.month, match.day)
}

Take it further: what if you could add a type annotation using any type that conformed to, say, LosslessStringConvertible, and the match would only succeed if the regex match was valid and all the type conversions succeeded?

let re = /(?<year: Int>\d{4})-(?<month: Int>\d{2})-(?<day: Int>\d{2})/
print(type(of: re))  // "Regex<(year: Int, month: Int, day: Int)>" 🤷🏻‍♂️

let match = re.match("2020-03-09")
  // match = (year: 2020, month: 3, day: 9)
let match = re.match("202X-03-09")
  // match = nil

This glosses over a lot of API complexity (like what if you need to iterate over multiple occurrences, or what if you need more information about the capture groups than just the text that was extracted, like the indexes into the string where they were found), but it would also be great to have an API that makes the simple cases extremely simple while also taking full advantage of the power of Swift's type safety.

33 Likes