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
.