I want to explore this area a bit more more thoroughly. The below is more of a first-principles approach and I'm not arguing that it should be API or not, nor am I saying what should happen now vs be considered as future work.
Casting
We have failable member function as go to a concrete type and an initializer to come from a concrete type.
Casting between AnyRegexOutput and the concrete output tuple creates Substrings from the internal storage representation (which only has a single strong reference to the input). This is convenient for use sites, but it is sub-optimal if the receiver doesn't actually need to materialize every Substring capture contained.
AnyRegexOutput <-> Output
To keep the storage representation, but get typed access, we can cast the Match object. This involves some run-time reflection, but doesn't materialize the individual Substrings.
Regex<AnyRegexOutput>.Match <-> Regex<Output>.Match
Finally, we can cast the regex itself such that it will produce concretely-typed matches when used.
Regex<AnyRegexOutput> <-> Regex<Output>
Querying captures
AnyRegexOutput is a collection of its existentially-typed captures (the first of which is the matched portion of the input). Note that this is the same as .count, so it's not super compelling to add this unless it helps with API consistency on a broader level.
AnyRegexOutput.captureCount: Int { get } // Same as `.count`
More compelling is adding this API to Match and Regex, whether existential or not:
Regex.Match.captureCount: Int { get }
Regex.captureCount: Int { get }
Asking whether a named capture is present and what its number is (straw-person names):
Regex.captureNumber(forNamed: String) -> Int?
Regex.Match.captureNumber(forNamed: String) -> Int?
AnyRegexOutput.captureNumber(forNamed: String) -> Int?
Or alternatively we could produce a Dictionary<String, Int> for convenience, noting that would require materializing the dictionary.
For getting the capture out, we can add (as Richard said) subscripts. However, I would strongly consider whether we should treat those subscripts as returning optional values instead of trapping. They are more analogous to dictionary's key-based subscript than its index-based subscript, especially in dynamically-constructed scenarios.
A similar question exists for the reference-taking subscript, where the references present are not reflected in the type signature. If there is separation in time/space between the Regex and its match, this can produce unexpected traps. The counter argument is that because these are actual instances of a Reference type, rather than arbitrary strings from who knows where, they are far more akin to indices than dictionary keys. This is especially so since these regex tend to be statically constructed. I find this counter argument compelling.
We mostly likely should, at the very least, have some way of querying presence of names and references without trapping.
One final note, perhaps AnyRegexOutput.Element should have a name of AnyRegexCapture, especially if we want to use this existential more prominently. On the other hand, its nice to have fewer top-level names.
I haven't thought too deeply about whether it's worth reifying the capture metatype to support more type-level operations directly on Regex (and this would clearly be severable).