Заменить две строки друг с другом

9

Я хотел бы изменить все вхождения строки (скажем, string1) с другой строкой (скажем, string2) и наоборот. Если быть точным, у меня длинный документ, и эти строки встречаются много раз. В настоящее время я заменяю string1 -> string3, затем string2 -> string1 и, наконец, string3 -> string2.

Мне интересно, если в Emacs уже есть функция, которая делает это. Другие решения приветствуются.

Изменить : Это на самом деле дубликат вопроса, указанного в комментарии. Но проблема в том, что принятый ответ на этот вопрос не всегда работает (см. Комментарий ниже). Я думаю, что лучше подождать, пока автор этого принятого ответа не исправит свой ответ или не появится какое-либо другое решение. Во-вторых, прежде чем опубликовать свой вопрос, я гуглил вопрос, и этот вопрос не появился. Я думаю, что иметь два дублирующих вопроса иногда полезно, так как они используют разные формулировки, и если пользователь найдет дублирующий, он / она сможет найти правильный.

Редактировать 2: приемлемый ответ функции поиска / замены для замены текста теперь, кажется, в порядке.

имя
источник
4
Возможный дубликат функции поиска / замены для замены текста
Т. Веррон
@ T.Verron Я пытался использовать принятый ответ по вашей ссылке, чтобы заменить «Это» на «это» в пустом буфере, но это не работает.
Имя
Может быть, я принял слишком быстро. Комментирование последних двух аргументов out ( backwardsи region-noncontiguous-p) в вызове perform-replaceзаставляет его работать здесь (emacs 24.3). Я протестирую его на emacs 25, когда у меня будет повод, прежде чем редактировать другой ответ.
Т. Веррон
@ T.Verron, напротив, другое решение, предлагающее использовать пакет plur. Кажется, работает в этой ситуации без проблем.
Имя
Я изменил принятый ответ в другом вопросе. Что касается Google, да, у меня тоже были проблемы с поиском ключевых слов, чтобы передать то, что я пытался сделать. И да, дубликаты хороши! blog.stackoverflow.com/2010/11/…
Т. Веррон

Ответы:

11

Для интерактивного случая query-replace-regexp (CM-%) может сделать это, используя относительно неизвестный \, для замены.

C-M-% \(string1\)\|\(string2\)
\,(if (equal \& "string1") "string2" "string1")

Если текст замены содержит \, за которым следует выражение lisp, в качестве замены используется значение этого выражения. В этом случае выражение представляет собой «если», которое принимает условие и возвращаемое значение для истинных и ложных случаев.

В комментариях предлагается использовать

\, (если \ 1 "string2" "string1")

Это работает, потому что \ 1 будет "string1", если шаблон соответствует string1, и будет равен nil в противном случае. Лисп принимает любое ненулевое значение за истину. Хотя это работает и короче, я думаю, что мой ответ более полезен. Я думаю, что этот код более удобен для чтения тем, чьи знания языка ограничены. У него есть второе преимущество, так как он все еще работает, если шаблон "from" задан как

\(string1\|string2\)

или даже

string1\|string2
Икар
источник
2
В некоторых комментариях к дублирующемуся кандидату предлагался более простой синтаксис \,(if \1 "string2" "string1")с использованием регулярного выражения \(string1\)\|string2.
Т. Веррон
Смотрите последние два абзаца (emacs) Regexp Replace.
Василий
-1

Ну, может быть, с макросом это будет легко:

F3C-saRETC-bM-tF4, Использование этого макроса в вашем вопросе выдает результат:

Я хотел бы изменить все вхождения строки a (скажем, string1) с другой строкой (скажем, string2) и наоборот. Если быть точным, у меня есть длинный документ, и эти строки встречаются много раз. В настоящее время я заменяю string1 -> string3, затем string2 -> string1 и, наконец, string3 -> string2.

Мне интересно, если в Emacs уже есть функция a, которая делает это. Другие решения приветствуются.

Я переставляю позиции между любым словом после aи этим словом. Позже вы можете редактировать такой макрос, чтобы транспонировать и другие слова без необходимости переопределять весь макрос, вы можете редактировать макрос с помощью C-xC-kRET.

shackra
источник
1
Я не думаю, что вопрос связан с транспонированием слов.
Т. Веррон
@ T.Verron Да, но он хочет более автоматизированный подход, кажется.
Шакра
1
То, что делает ваш макрос, обменивается (транспонирует) каждое «а» со следующим словом. "строка"> "строка а" и т. д. Он хочет заменить, например, каждое "а" на "а" и каждое "то" на "а".
Т. Веррон