Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find/Replace in Xcode using Regular Expression

I have the following function calls at several places in my class.

[myClass doOperationOne]; [myClass doOperationTwo]; [myClass doOperationThree]; 

In those lines, I want to search for the following,

[myClass doOperationOne [myClass doOperationTwo [myClass doOperationThree 

And replace them with the following, (by appending WithOptions:[Permissions isOptionsAvailable])

[myClass doOperationOneWithOptions:[Permissions isOptionsAvailable]]; [myClass doOperationTwoWithOptions:[Permissions isOptionsAvailable]]; [myClass doOperationThreeWithOptions:[Permissions isOptionsAvailable]]; 

How can I do this using single Regular Expression Find/Replace?

like image 899
EmptyStack Avatar asked Jan 24 '11 05:01

EmptyStack


People also ask

How do I find and replace in Xcode?

Click on 'Find' (in the search navigator) and choose 'Replace' from the dropdown.

Can you use regex in Find and Replace?

When you want to search and replace specific patterns of text, use regular expressions. They can help you in pattern matching, parsing, filtering of results, and so on. Once you learn the regex syntax, you can use it for almost any language. Press Ctrl+R to open the search and replace pane.

How do you replace all words in Xcode?

Xcode displays the results of the search, but it doesn't automatically replace the text. To replace the text for a single result, select it and click the Replace button. To replace the text for all results, click Replace All.

How do you substitute in regex?

Match a white space followed by one or more decimal digits, followed by zero or one period or comma, followed by zero or more decimal digits. This is the first capturing group. Because the replacement pattern is $1 , the call to the Regex. Replace method replaces the entire matched substring with this captured group.


2 Answers

NOTE: The behavior changed in Xcode 6. The \123 syntax was replaced with $123. Also be warned that newlines can now be matched in reg exps so be sure to skim before Replace-Alling

Adding an additional argument to a method:

To replace

[* setFoo:*] 

with

[* setFoo:* bar:value] 

you do

(setFoo:)(.*)(\]) $1$2 bar:value] 

(search string and replacement string respectively).

or, if on Xcode 5 or older

(setFoo:)(.*)(\]) \1\2 bar:value] 

(below uses new syntax; swap if on Xcode 5 or older)

NOTE: Everything written here applies to the string-replacement methods in NSString/NSMutableString when using NSRegularExpressionSearch!

In other words, this line:

[input replaceOccurrencesOfString:@"\n\\[([^\\]^\n]*)\\]\n"                         withString:@"\n///\n\n[$1]\n"                            options:NSRegularExpressionSearch                             range:(NSRange){0,input.length}]; 

will convert all "[...]\n" sequences (leaving e.g. "[...\n..." alone!) into "\n///\n\n[...]\n", preserving ... using $1.

Always did this by hand but in this case, I was adding an OPTIONAL 'animate:' flag, and the default up to this point had been YES, but I wanted NO, so every call had to be updated.

More examples:

Deprecated methods (iOS)

dismissModalViewControllerAnimated:... deprecation

To fix the deprecated dismissModalViewController replacing it with an empty completion block and retaining animated value:

(dismissModalViewControllerAnimated:)(.*)(\]) dismissViewControllerAnimated:$2 completion:nil] 

presentModalViewController:animated: deprecation

(presentModalViewController:)(.*)( animated:)(.*)(\]) presentViewController:$2$3$4 completion:nil] 

Miscellaneous

PD...Release → PD...Destroy

I recently wrote a c library with a bunch of files with the prefix PD and I used Create/Release as malloc/free keywords, which I regretted as it may make people think retain counting is kept, so I wanted to renamePD<anything>Release( with PD<anything>Destroy(.

([\n\r ])(PD)(.*)Release\( $1$2$3Destroy( 

Since Core Graphics has CGPDFDocumentRelease and similar, I had to ensure the word started with PD as well.


PDAssert(PDScannerPop...(...));

I had stupidly put assertions around functional code that would become empty when !#ifdef DEBUG. Luckily I knew that all of these started with PDAssert(PDScannerPop.... and ended with );.

(PDAssert\()(PDScannerPop)(.*)(\);) $2$3; 

No $1 here because that would include the PDAssert( again. Note that I've split right after the PDAssert( and am leaving out the ) in ); in the 3rd chunk which removes the surplus parens from removing PDAssert(.

Dealing with end parentheses

You can match everything except ")" to deal with over-greedy regexp replaces. Example:

foo(replace(arg), bar) foo(newvalue(newarg), bar) 

Using replace\((.*)\) will grab replace(arg), bar) and result will be foo(newvalue(newarg)! Instead use replace\(([^\)]*)\) which will grab replace(arg) and leave , bar) alone.

Converting a bunch of NSString properties from using retain and/or strong (and whatever else) to using copy

@property \(([^\)]*)[sr][te][rt][oa][ni][gn]([^\)]*)\)(.*)NSString(.*) @property ($1copy$2)$3NSString$4 

The weird sr te rt thing in the center matches both "strong" and "retain".

like image 169
Kalle Avatar answered Sep 22 '22 00:09

Kalle


Somehow I've managed to find the answer (which is enough for my need here) by referring the post: http://www.cocoabuilder.com/archive/xcode/273123-how-to-use-regular-expressions-in-xcode-find-replace.html, and trial and error method.

My Find string is:

(\[myClass.myMethod )(.*)(\];) 

And, my Replace string is:

\1\2WithOptions:[Permissions isOptionsAvailable]\3 

Please post if there is any better way than this..

like image 37
EmptyStack Avatar answered Sep 22 '22 00:09

EmptyStack