Search and Replace in Xcode with Regular Expressions

Recently I ran into problem where I wanted to search a pattern through project and replace it with another one. In the past I have really hard time dealing with Regular expressions. This time I decided I was going to learn more about them and if possible write a post about how to use them. So here we go - How to Search and Replace in Xcode with Regular Expressions

Enabling search and replace with regular expressions option in Xcode


######Finding with regular expression To find a keyword with RegEx, go to project navigator in left side pane. Select `Find` and then select `Regular Expression` option. This will enable finding with given regular expression statement

enable_regex_search

Replacing with regular expression

To replace a keyword with RegEx, go to the same project navigator in left side pane. Select Replace and then select Regular Expression option. This will enable replacing with given statement with regular expression format

enable_regex_replace

Searching for an expression in Xcode project

  • Say I want to search methods in project which take NSString as an input and return nothing. For example,

- (void)foo:(NSString*)foo

I can simply do


- \(void\)(.*):\(NSString\*\)(.*) \{

What this expression does is, it tells the search operator not to worry about method name and named parameter associated with methods matching given regular expression.

The values matching the given RegEx can be extracted using variable $1 and $2 in the example above. As you may have noted, RegEx won't work with special characters such as open-close brackets. You will have to escape them manually using backslash characters to enable searching on them.

So if you run into problem with RegEx containing special characters, make sure you escape them before performing any more debug steps.

To give you another example, say I want to find all return statements returning array count, I can use either of following statements. (Depends on your coding guidelines)

return \[(.*) count\] or return (.*).count.

Where name of the array in question is stored in special variable $1

Replacing an expression in the Xcode project

  • Now since we are past the initial formalities, let's dive into slightly more complex RegEx operation of replacing an expression. Let's continue from couple of previous examples.

As we saw, - \(void\)(.*):\(NSString\*\)(.*) \{ can be used to search all methods taking NSString as an input parameter and returning nothing. Let's say we want to replace them by another parameter, say bar. So all method like

- (void)foo:(NSString*)foo will now look like,

- (void)foo:(NSString*)foo andBar:(NSString*)bar.

How do we do it?

solution is simple. You get all expressions matching with given RegEx into pre-determined variables such as $1, $2 and so on. So all you have to do it, just put them into replacement string and append any extra expression you want. Using the same principle, we can perform replacement with following string.
Search for,

- \(void\)(.*):\(NSString\*\)(.*) \{

And replace it with,

- \(void\)$1:\(NSString\*\)$2 andBar:(NSInteger)bar \{

Here, original method signature remains unchanged and that's why we chose to re-use them in the form of $1 and $2. and final result throughout your project is,

- (void)foo:(NSString*)foo andBar:(NSInteger)bar {

On the similar note, if you have changed your internal guidelines, and decided to follow another syntax to get NSArray count. ([array count] to array.count), this can be done with following RegEx.

Simply replace

\[(.*) count\]

with

$1.count

It will replace all message sendings with parameter access for NSArray

Update:

We recently ran a SwiftLint on our codebase and caught few warnings related to legacy functions.

For example, lint tool asked me to replace older CGRectMake with CGRect and so on. Below is how I did to find and replace other legacy expressions

  • CGRectMake

// Searching all legacy `CGRectMake` structs
// Search with following RegEx
CGRectMake\([ ]{0,1}(.*),[ ]{0,1}(.*),[ ]{0,1}(.*),[ ]{0,1}(.*)\)
// [ ]{0,1} says value followed by zero or more spaces. 
// We use this because of uncertain number of spaces before comma. 
// (.*) captures values in the form of $1, $2, etc.

// Replacing all legacy `CGRectMake` structs with new syntax

// Replace the found RegEx with following expression
CGRect\(x: $1, y: $2, width: $3, height: $4\)
// Where $1, $2 represent the values caught by previous expression matching values in the form (.*) around commas.

  • CGSize

// RegEx to search for
CGSizeMake\([ ]{0,1}(.*),[ ]{0,1}(.*)\)

// RegEx to replace with 
CGSize\(width: $1, height: $2\)

  • NSMakeRange

// RegEx to search for
NSMakeRange\([ ]{0,1}(.*),[ ]{0,1}(.*)\)

// RegEx to replace with 
NSRange\(location: $1, length: $2\)

Hope this helps if you are dealing with relatively large codebase. Simple expressions are easy to search and replace, but if you can use RegEx to search and replace complex expressions, why not? Still better than manual search and replace which is more prone to human errors

Thanks to This post by Road fire software which was a great resource and inspiration for this post

Jayesh Kawli

I am a web and mobile developer working at Wayfair in Boston, MA. I come to learn so many things during course of life and I write about things which helped me and feel like they can help others too.

Subscribe to Fresh Beginning

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!