Найти / заменить в XCode, используя регулярное выражение - PullRequest
43 голосов
/ 24 января 2011

У меня есть следующие вызовы функций в нескольких местах в моем классе.

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

В этих строках я хочу найти следующее,

[myClass doOperationOne
[myClass doOperationTwo
[myClass doOperationThree

И заменить их наследующее (добавив WithOptions:[Permissions isOptionsAvailable])

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

Как я могу сделать это с помощью одного поиска / замены регулярного выражения?

Ответы [ 5 ]

62 голосов
/ 04 марта 2013

ПРИМЕЧАНИЕ. Поведение изменилось в Xcode 6. Синтаксис \ 123 был заменен на $ 123.Также имейте в виду, что теперь новые строки могут быть сопоставлены в reg exps, поэтому убедитесь, что просматриваете их перед Replace-Alling

Добавление дополнительного аргумента в метод:

Для замены

[* setFoo:*]

с

[* setFoo:* bar:value]

вы делаете

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

(строка поиска и строка замены соответственно).

или, если на Xcode 5 или старше

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

(ниже используется новый синтаксис; поменяйте местами, если на Xcode 5 или старше)

ПРИМЕЧАНИЕ. Все написанное здесь относится к методам замены строк в NSString / NSMutableString при использовании NSRegularExpressionSearch!

Другими словами, эта строка:

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

преобразует все "[...]\n" последовательности (оставляя, например, "[...\n..." в покое!) в "\n///\n\n[...]\n", сохраняя ... с использованием $ 1.

Всегда делал это вручную, но в этом случае я добавлял ФАКУЛЬТАТИВНЫЙ флаг 'animate:', и по умолчанию до этого момента было ДА, но яхотел НЕТ, поэтому каждый вызов должен был обновляться.

Больше примеров:

Устаревшие методы (iOS)

dismissModalViewControllerAnimated:... deprecation

Чтобы исправить устаревший dismissModalViewController, заменив его пустым блоком завершения и сохранив анимированное значение:

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

presentModalViewController:animated: deprecation

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

Разное

PD ... Релиз → PD ... Уничтожить

Я недавно написал ac библиотеку с кучей файловс префиксом PD, и я использовал Create / Release в качестве ключевых слов malloc / free, о чем я пожалел, так как это может заставить людей думать, что сохранение подсчета сохранено, поэтому я хотел переименовать PD<anything>Release( с помощью PD<anything>Destroy(.

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

Поскольку Core Graphics имеет CGPDFDocumentRelease и аналогичные значения, я должен был обеспечить, чтобы слово начиналось также с PD.


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

Я тупо поставил утверждения вокруг функционального кода, который станет пустым, когда! #Ifdef DEBUG.К счастью, я знал, что все это началось с PDAssert (PDScannerPop .... и закончилось с) ;.

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

Здесь нет $ 1, потому что это снова включит PDAssert(.Обратите внимание, что я разделился сразу после PDAssert (и опускаю) в;в третьем фрагменте, который удаляет лишние парены из удаления PDAssert (.

Работа с конечными скобками

Вы можете сопоставить все, кроме ")"иметь дело с чрезмерно жадным регулярным выражением замен.Пример:

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

Использование replace\((.*)\) захватит replace(arg), bar), и результат будет foo(newvalue(newarg)!Вместо этого используйте replace\(([^\)]*)\), который захватит replace(arg) и оставит , bar) в покое.

Преобразование набора свойств NSString из использования retain и / или strong (и любого другого) в использованиеcopy

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

Странная вещь в центре совпадает как с "сильным", так и с "удержанием".

42 голосов
/ 24 января 2011

Каким-то образом мне удалось найти ответ (которого мне здесь достаточно), сославшись на сообщение: http://www.cocoabuilder.com/archive/xcode/273123-how-to-use-regular-expressions-in-xcode-find-replace.html, и метод проб и ошибок.

Мой Найти строка:

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

И, моя Заменить строка:

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

Пожалуйста, напишите, если есть лучший способ, чем этот ..

16 голосов
/ 26 июля 2015

Примечание для Xcode 8

Я пытался обновить свой ответ ниже для Xcode 8, но не смог этого сделать. Если у вас есть ответ, пожалуйста, дайте мне знать.

Xcode 7

Если вы уже не были гением с регулярными выражениями, это намного проще сделать в Xcode сейчас.Вам вообще не нужно использовать регулярные выражения (но вы можете это сделать, если хотите).

Пример

Заменить эти строки:

[myClassdoOperation Один ];
[myClass doOperation Два ];
[myClass doOperation Три ];

сэти строки

[myClass doOperation One WithOptions: [Permissions isOptionsAvailable]];
[myClass doOperation Two WithOptions: [Permissions isOptionsAvailable]];
[myClass doOperation Три WithOptions: [Permissions isOptionsAvailable]];

Номера, выделенные полужирным шрифтом, показывают, почему не работает простой поиск и замена.

Настройка

Существует два способа поиска и замены: Текстовое и Регулярное выражение

Нажмите на увеличительное стекло

enter image description here

и «Изменить параметры поиска»... "

enter image description here

и выберите один из них.

enter image description here

Метод 1 - Текстовый

  • Введите [myClass doOperation в Найти

  • Щелкните по классу увеличения и выберите «Вставить шаблон»

enter image description here

  • Выберите «Любые символы слова»

enter image description here

  • Добавить ]; для поиска

enter image description here

  • Повторите для строки замены, но используйте WithOptions:[Permissions isOptionsAvailable]]; для последней части.

enter image description here

  • Один Заменить все теперь будет работать.

Способ 2 - Регular Expression

  • Убедитесь, что регулярные выражения выбраны, как описано в разделе «Настройка» выше.

  • Используйте (\[myClass doOperation)(.*)(\];) для регулярного выражения

  • Используйте $1$2WithOptions:[Permissions isOptionsAvailable]$3 для строки замены.$1, $2 и $3 заменяют скобки в регулярном выражении.

enter image description here

  • Один Заменить все теперь будет работать.

  • См. эту ссылку для получения дополнительной помощи с регулярными выражениями.

См. Также

1 голос
/ 24 января 2011

В текущей версии XCode, я полагаю, вы можете искать только с использованием регулярных выражений. Замена не дает вам такой гибкости. Если у вас есть только три метода, которые вы хотите заменить таким образом, я бы запустил поиск и замену три раза. В противном случае я бы изменил свой исходный код в BASH, используя awk или sed.

1 голос
/ 24 января 2011

Я не могу найти что-либо, говорящее, что захват и замена регулярных выражений поддерживается В Xcode.

вы хотите, чтобы

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

захватил номер.хоть.это то, для чего скобки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...