I'm very new to Swift, so pardon my ignorance (again), but I'm trying to build Swift examples that will run on Windows, Linux, and Mac. And noticed a different behavior only on Windows. When doing something like this:
This works as-is on the Mac and Linux, but on Windows, I have to surround it with quotation marks, like this:
Is this the expected behavior? If so, I have to add preprocessor directives when running on Windows.
The first is a raw regex literal demarcated by #/ and /#. The second is a raw string literal demarcated by #" and "#. Regex literals are technically an optional feature available in Swift 5.7 and above. On macOS and Linux you must be using that newer version with the literals enabled. On Windows perhaps you're using an older version, or perhaps you haven't enabled the feature with the appropriate flag (which I don't recall).
As Jon has explained, the /…/ and #/…/# are called bare-slash regex literals, which is not supported on Windows due to broken bootstrapping support. You cannot enable it even with a flag.
In Xcode 14+, the syntax is enabled by default, but you shouldn’t expect it to be available without a flag with regular Swift 5.7 toolchains.
I don’t know how you had it “just worked” on Linux, but as long as you’d like to preserve Swift 5 compatibility, type-annotated regex created with string literal should be preferred.
This explanation is not correct. #/.../# is not a bare regex literal, and it should not require any compiler flag to use on any platform. If Windows builds do not support regex literals, that's a bug that needs to be fixed.
So it seems I misunderstood the concept of a bare regex literal, thanks for pointing out.
Regex literals are not understood by Swift compiler on Windows due to missing bootstrapping step (I’m surprised that this is an enabled feature because Implementing Parts of the Swift Compiler in Swift was posted long after Swift 5.7 branch cut-off).
To try getting it enabled, we may need to enable bootstrapping without SIL optimization module. Not sure if it’s supported now.
These are not equivalent expressions. The first one searches for the first part of the string that matches the regex, while the second one searches for the first part of the string that’s equivalent to the string passed as an argument.
You can see the difference here:
"x0y1".firstMatch(of: #/\w(\d.\d)/#) // match succeeds
"x0y1".firstMatch(of: #"/\w(\d.\d)/"#) // match fails
#"abcd/\w(\d.\d)/efgh"#.firstMatch(of: #/\w(\d.\d)/#) // match fails
#"abcd/\w(\d.\d)/efgh"#.firstMatch(of: #"/\w(\d.\d)/"#) // match succeeds