Find/Replace in Xcode using Regular Expression

前端 未结 6 1587
不思量自难忘°
不思量自难忘° 2020-12-04 10:43

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

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

相关标签:
6条回答
  • 2020-12-04 11:28

    In the current version of Xcode, I believe you can only search using regular expressions. Replace doesn't give you that flexibility. If you only have three methods you want to replace in this manner, I would run search and replace three times. Otherwise, I would modify my source code in BASH using awk or sed.

    0 讨论(0)
  • 2020-12-04 11:33

    Note for Xcode 8

    I was trying to update my answer below for Xcode 8, but I couldn't do it. If you have the answer, please let me know.

    Xcode 7

    Unless you were already a regular expression genius, this much easier to do in Xcode now. You don't need to use regular expressions at all (but you can if you still want to).

    Example

    Replace these strings:

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

    with these strings

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

    The bolded numbers show why a plain Find and Replace won't work.

    Setup

    There are two ways you can do Find and Replace: Textual and Regular Expression

    Click the magnifying glass

    and "Edit Find Options..."

    and choose one of them.

    Method 1 - Textual

    • Enter [myClass doOperation in Find

    • Click the magnifying class and choose "Insert Pattern"

    • Choose "Any Word Characters"

    • Add ]; to Find

    • Repeat for the Replacement String but use WithOptions:[Permissions isOptionsAvailable]]; for the last part.

    • A single Replace All will work now.

    Method 2 - Regular Expression

    • Make sure that Regular Expressions are selected as described in Setup above.

    • Use (\[myClass doOperation)(.*)(\];) for the Regular Expression

    • Use $1$2WithOptions:[Permissions isOptionsAvailable]$3 for the Replacement String. The $1, $2, and $3 replace the parentheses in the regular expression.

    • A single Replace All will work now.

    • See this link for more help with regular expressions.

    See also

    • How can I find and replace inside a selection in Xcode?
    0 讨论(0)
  • 2020-12-04 11:34

    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".

    0 讨论(0)
  • 2020-12-04 11:35

    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..

    0 讨论(0)
  • 2020-12-04 11:40

    I can't find anything saying that regular expression capture and replace is supported WITHIN Xcode.

    you would want

    \[myClass\.myMethod\sdoOperation([A-Z][a-z]+)\] 
    

    to capture the number. though. that is what the parenthesis are for.

    0 讨论(0)
  • 2020-12-04 11:40

    on Xcode 11+

    for example:

    when you use view(.*)Appear to find all viewDidAppear or viewWillAppear

    and replaced by args: $1

    You will get the result as follow

    Don't forget to use () to wrap the .*, or you will get an empty result.

    0 讨论(0)
提交回复
热议问题