swiftregexswitch-statementswift5.7

How to use Swift literal regex expressions in switch case pattern statements?


How to use Swift literal regex expressions in switch case pattern statements?

Based on the examples from WWDC 2022 presention slides, the following is expected to compile and run OK:

import Foundation
import RegexBuilder

switch "abc" {
    case /\w+/:
        print("matched!")
    default:
        print("not matched.")
}

However, the following error is produced:

Expression pattern of type Regex<Substring> cannot match values of type String

Can the switch case statement with a Swift regex literal expression be somehow modified to function OK? How would one use the new Swift 5.7 regex capabilties in the switch case pattern statement?


Solution

  • From what I have found, the "matching with regexes in switch statement" feature has not been implemented, because people were arguing about what the exact semantic should be. In case such as

    switch "---abc---" {
    case /\w+/:
        print("foo")
    default:
        print("bar")
    }
    

    which branch should the switch statement run? Should it count as a match only if the whole string matches the regex, or is it enough only for a substring of the switched string to match? In other words, is it wholeMatch or firstMatch? See more of the discussion here.

    In the end, they were not able to come to a conclusion, and

    The proposal has been accepted with modifications (the modification being to subset out ~= for now).

    So the ~= operator was not added for Regex<Output>, so you cannot use it in a switch.

    You can add it yourself if you want, if you can decide between the two semantics :) For example:

    func ~=(regex: Regex<Substring>, str: String) -> Bool {
        // errors count as "not match"
        (try? regex.wholeMatch(in: str)) != nil
    }