Swift Regex introduced in Swift 5.7

Ryuichi / Rick
5 min readSep 28, 2022

--

Photo by Carli Jeen on Unsplash

Hi there, I’d like to show you how to use Swift Regex, which was introduced in Swift 5.7🎉

How we use the regex before introducing Swift Regex?

When not to use Swift Regex, we use the things below.

  1. NSRegularExpression
  2. The methods come from NSString
    range(of:options:range:locale:)
    replacingOccurrences(of:with:options:range:)
    ・etc…
The example of validating a {year}-{month{-{day} format using NSRegularExpression

Here are the reasons that I think NSRegularExpression is such a fiddly thing to use :(

  1. We have to use “try” just to instantiate NSRegularExpression class, so this makes us think about the situation some errors occur.
  2. To write a regex, we have to write double escape.
  3. To get the final achievement, we have to use NSRange and Range.
  4. Optional binding(I’ve omitted in the example above) is needed to get the result.

But fortunately, we don’t have to be bothered if we use Swift Regex 🎉

What is the advantages of Swift Regex compared to the old one?

“Meet Swift Regex” 6:28

1. Literals are concise; builders give structure.

It looks apparently more intuitive when we use Swift Regex and Regex builders(thanks to resultBuilder which is described later).

The comparison of NSRegularExpression and Swift Regex

2. Interweave real parsers as parts of regex

We can use the parsers which has originally existed parsers. (i.e., Date.ParseStrategy)

“Meet Swift Regex” 8:57

And more, we can use custom parser if we prepare the type conforming CustomConsumingRegexComponent.

How to CustomConsumingRegexComponent

3. Regex does Unicode
These two features have been implemented.
i: Canonical Equivalents
ii: Extended Grapheme Clusters and Character Classes with Strings

4. Predictable execution, prominent controls
If we use Swift Regex, we can get advantage of the reasoning, and reduce mistakes at compile-time!

We can get advantage of reasoning.

How to use a Swift Regex?

There are 3 ways to use it.

1. Regex literals

We can write really concisely. Actually, we don't have to write double escape and consider do-catch anymore unlike NSRegularExpression! Awesome!!

How to use Regex literals

2. Run-time construction

This is useful for search fields in editors or command-line tools.
This will throw an error at run-time if the input of Regex.init(_:) is invalid. The output type will be AnyRegexOutput though. Here is the way to extract the value.

How to use Run-time construction

We can extract the result by using extractValues(as:), but I couldn’t get the value if I try to use String.self as input.
As a side note, the content of match.output was like this.

AnyRegexOutput(input: “2023–03–20”, _elements: [_StringProcessing.AnyRegexOutput.ElementRepresentation(optionalDepth: 0, content: Optional((range: Range(Swift.String.Index(_rawBits: 15)..<Swift.String.Index(_rawBits: 655367)), value: nil)), name: nil, referenceID: nil)])

3. Regex builders

I suppose this is the most well-structured way to write!
It is really intuitive way to read!! And of course, a bunch of fiddly things which is required for NSRegularExpression is no longer needed 🎉

How to use Regex builders

And the reason why we can write Regex in such an intuitive way is resultBuilder. Here is the actual implementation.

How Regex builder is implemented

Some types which we can use to build Regex 🎉

I’d like to show you some types which conform to RegexComponent. We can use these types for instantiating Regex.

One

This is the type to prove there is only one thing specified at input(which is date(_:locale:timeZone:calendar:) in the example below).
If there is 0 or more than 2, the content of “match” would be nil.

How to use One

ZeroOrMore

This is the type to prove there aren’t different characters other than specified one. Thus, even if specified characters are not there, it’s ok.

How to use ZeroOrMore

OneOrMore

This is the type to prove there are more than one specified characters. Thus, if there is no specified characters, the content of “match” would be nil.

How to use OneOrMore

Repeat

This is the type to prove there are the specified number of specified characters.

Capture

If we use this, we can extract each value from a specified key!

How to use Capture along with Regex builders

We don’t have to specify the type of each key if we use Regex literals :)

How to use Capture along with Regex literals

TryCapture

If we use this, we can transform the captured value and convert it!

How to use TryCapture

Tips 👩‍💻

Xcode features

You can convert from Regex builders to Regex literals automatically like this! Perfect! Thus, even though you are not familiar Regex builders, it’s fine!

The feature by Xcode to convert into Regex builders

--

--