Declarative String Processing Overview

This code:

guard let (l, u, p) = line.match(/([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s*;\s(\w+).*/).captures else {
    handleFailure()
}
// use l, u, and p

would work (assuming captures is an Optional property). It’s more verbose than your example, but it’s still clear.

We could add a method to “regular-expressible” types called captures(from: RegEx) that would would be equivalent to match(_: RegEx).captures.


This confusion over where to put an API has come up before — I think we need official guidance from the Core Team on how to decide whether an API should go into the standard library, Foundation, or a separate package. For now, though, here are the rules I follow:

  • If an API is meant for general-purpose use and doesn’t rely on operating system services (i.e. numbers, collections, and collection algorithms), then it should go in the standard library.
  • If an API is meant for general-purpose use and relies on operating system services (i.e. networking), then it should go in Foundation.
  • If an API is meant for a specific domain of programming (like complex numbers) or we want to test-drive an API before its inclusion in the standard library / Foundation (like some Swift Collections algorithms), then we should put it in a separate package.

I’d consider regular expressions and Pattern as being meant for general-purpose use, so IMO they should go in the standard library.


I don’t think we should avoid regular expressions just because of their obscure syntax — regexes can be very useful in the right context. While it’s true that regular expressions can obfuscate the meaning of code, being too verbose can also obfuscate code. I think that allowing regexes within Pattern builders is a good way to help balance the obscurity of regexes with the verbosity of Pattern. Good documentation on Swift’s regular expression syntax should also help with reading regexes.

I don’t think that it’s possible to create a regex-like “convenient and powerful pattern-matching syntax that reads like normal Swift code” — as @xwu pointed out earlier in the thread, making Pattern more terse or making regular expressions more readable would lead to undesirable compromises.


I think named captures should be part of Swift’s pattern-matching syntax. So it would be something like

guard case /^(?<let key>\w+)=(?:(?<let number>\d+)|(?<let string>\S+))$/ else {
    handleFailure()
}
//use key, number, and string

(Obviously, we should use a Swiftier syntax for this.)


Have we considered combining the RegEx and Pattern types? Regular expression literals could simply be a shorthand syntax for Pattern.

2 Likes