Removing captures from regex type

I have a regex that matches single-line raw string literals (ignoring interpolation), which looks like this:

let ref = Reference<Substring>()
let rgx = Regex {
  Capture(OneOrMore("#"), as: ref)
  "\""
  ZeroOrMore(ChoiceOf {
    CharacterClass.anyOf("\"").union(.newlineSequence).inverted
    Regex {
      "\""
      NegativeLookahead(ref)
    }
  })
  "\""
  ref
}

I want to return this from a function that gives Regex<Substring> on all other code paths, but this is Regex<(Substring, Substring)>. I thought I could be clever and add transform: { _ in } to the capture, but that just makes it Regex<(Substring, Void)>. Is it possible to erase the capture group from the type of the regex and have its output only report the full match, or do I have to rewrite the function's callers to work with Regex<AnyRegexOutput>? (If the latter, I'll also have to modify all the other code paths, because instead of just .init { ... } they'll have to say .init(Regex { ... }).)

2 Likes

SE-0351 mentions a mapOutput method that would let you discard the captured group, but it hasn't been implemented yet:

1 Like

That sounds like exactly what I was looking for! Unfortunate that it was never finished.

Yes, mapOutput is what you want. It didn't make the initial release, but we're working on it currently.

In the mean time, you can use the existential AnyRegexOutput as you mentioned. You might also be able to make some of your functions generic over the capture types.

4 Likes

As I said in the original post, this is used for the return value of a function. Unless I can return any Regex, I don’t think that would work.

Thanks for posting this. I've been trying to figure out how to handle nested Captures and trying to get mapOutput to work using Xcode 15.1b1.

It seems like this would be really helpful to have added sooner than later. TIA.