How to refactor code with regular expressions š¤Æ
Hi š
To begin this new week, Iām going to show you another āuseful but hiddenā feature of Xcode!
But first, I have a big thank you for the sponsor of this email: Runway
Advertisement
Sponsors like Runway really help me grow my content creation, so if you have time please make sure to check out their survey: itās a direct support to my content creation āŗļø
Iām sure that youāve already used the Refactor feature of Xcode.
When you need to rename an identifier thatās used in several places across your project, the Refactor feature saves you a lot of time by automatically performing all the renaming at once.
However, there are some situations where the Refactor feature is actually too limited for the way that we want to update our code.
For example, consider this piece of code:
As you can see, this code calls the function NSLocalizedString()
to retrieve several user-facing localized strings.
Now, letās imagine that we want to encapsulate the call to NSLocalizedString()
inside a computed property of the type String
:
If you try to use the Refactor feature to automatically update the calls of the function NSLocalizedString()
with calls of the property .localized
, you will quickly realize that itās actually not possible.
However, itās still possible to have Xcode automatically update all the call sites for us: weāre going to use the Find & Replace feature along with a regular expression!
For this, in Xcode switch to the Find navigator and instead of Text, select Regular Expression:
Then, type the following regular expression: NSLocalizedString\((".*"), comment: ""\)
As you can see, this regular expression successfully matches all of the call sites:
Letās take a moment to understand how this regular expression was built.
First, we start with one of the call sites:
NSLocalizedString("person.title", comment: "")
Then, we add '/'
to escape the parenthesis, which are special characters in a regular expression:
NSLocalizedString\("person.title", comment: ""\)
Next, we replace the part that will be different for each call with '.*'
, which will match any non-empty sequence of characters:
NSLocalizedString\(".*", comment: ""\)
Finally, we add parentheses around the pattern '(".*")'
, to state that we want to capture the part of the string that matches the pattern:
NSLocalizedString\((".*"), comment: ""\)
With this regular expression weāve done half of the job, now letās move on to the other half: replacing the old call sites by the new ones.
In Xcode, click on Find and select Replace instead:
And then type: $1.localized
In this syntax, $1
refers to the part of the regular expression that was between parentheses and that was captured.
This means that $1
will contain the key of the localized string, to which we will append the call to the computed property .localized
.
Finally, we can click on Replace All:
And thatās it, all the call sites have been automatically updated āļø
In the past, there have been situations where this feature has saved me quite a lot of time!
So now that youāve learned how to use it, I hope that it will be the same for you š
Thatās all for this email, thanks for reading it!
If youāve enjoyed it, feel free to forward it
to your friends and colleagues š
I wish you an amazing week!
ā¤ļø