Я хотел бы изменить все вхождения строки (скажем, string1) с другой строкой (скажем, string2) и наоборот. Если быть точным, у меня длинный документ, и эти строки встречаются много раз. В настоящее время я заменяю string1 -> string3, затем string2 -> string1 и, наконец, string3 -> string2.
Мне интересно, если в Emacs уже есть функция, которая делает это. Другие решения приветствуются.
Изменить : Это на самом деле дубликат вопроса, указанного в комментарии. Но проблема в том, что принятый ответ на этот вопрос не всегда работает (см. Комментарий ниже). Я думаю, что лучше подождать, пока автор этого принятого ответа не исправит свой ответ или не появится какое-либо другое решение. Во-вторых, прежде чем опубликовать свой вопрос, я гуглил вопрос, и этот вопрос не появился. Я думаю, что иметь два дублирующих вопроса иногда полезно, так как они используют разные формулировки, и если пользователь найдет дублирующий, он / она сможет найти правильный.
Редактировать 2: приемлемый ответ функции поиска / замены для замены текста теперь, кажется, в порядке.
backwards
иregion-noncontiguous-p
) в вызовеperform-replace
заставляет его работать здесь (emacs 24.3). Я протестирую его на emacs 25, когда у меня будет повод, прежде чем редактировать другой ответ.Ответы:
Для интерактивного случая query-replace-regexp (CM-%) может сделать это, используя относительно неизвестный \, для замены.
Если текст замены содержит \, за которым следует выражение lisp, в качестве замены используется значение этого выражения. В этом случае выражение представляет собой «если», которое принимает условие и возвращаемое значение для истинных и ложных случаев.
В комментариях предлагается использовать
Это работает, потому что \ 1 будет "string1", если шаблон соответствует string1, и будет равен nil в противном случае. Лисп принимает любое ненулевое значение за истину. Хотя это работает и короче, я думаю, что мой ответ более полезен. Я думаю, что этот код более удобен для чтения тем, чьи знания языка ограничены. У него есть второе преимущество, так как он все еще работает, если шаблон "from" задан как
или даже
источник
\,(if \1 "string2" "string1")
с использованием регулярного выражения\(string1\)\|string2
.(emacs) Regexp Replace
.Ну, может быть, с макросом это будет легко:
F3C-s
a
RETC-bM-tF4, Использование этого макроса в вашем вопросе выдает результат:Я переставляю позиции между любым словом после
a
и этим словом. Позже вы можете редактировать такой макрос, чтобы транспонировать и другие слова без необходимости переопределять весь макрос, вы можете редактировать макрос с помощью C-xC-kRET.источник