Remplacez deux chaînes l'une avec l'autre

9

Je voudrais changer toutes les occurrences d'une chaîne (disons chaîne1) avec une autre chaîne (disons chaîne2) et vice-versa. Pour être précis, j'ai un long document et ces chaînes se produisent plusieurs fois. Ce que je fais actuellement, c'est de remplacer string1 -> string3, puis string2 -> string1 et enfin string3 -> string2.

Je me demande s'il y a déjà une fonction dans emacs qui fait ça. D'autres solutions sont les bienvenues.

Modifier : il s'agit en fait d'un doublon de la question liée dans le commentaire. Mais le problème est que la réponse acceptée à cette question ne fonctionne pas toujours (voir le commentaire ci-dessous). Je pense qu'il vaut mieux attendre que l'auteur de cette réponse acceptée corrige sa réponse ou qu'une autre solution sorte. Deuxièmement, avant de poster ma question, j'ai googlé la question et cette question ne s'est pas présentée. Je pense qu'avoir deux questions en double est parfois utile car elles utilisent des termes différents et si un utilisateur en trouve une en double, il peut trouver la bonne.

Edit 2: La réponse acceptée de la fonction de recherche / remplacement pour l'échange de texte semble bien maintenant.

Nom
la source
4
Duplication possible de la fonction de recherche / remplacement pour l'échange de texte
T. Verron
@ T.Verron J'ai essayé d'utiliser la réponse acceptée de votre lien pour remplacer "This" par "that" dans le tampon de travail mais cela ne fonctionne pas.
Nom
J'ai peut-être accepté trop vite. Commenter les deux derniers arguments ( backwardset region-noncontiguous-p) dans l'appel de perform-replacefait fonctionner ici (emacs 24.3). Je vais le tester sur emacs 25 lorsque j'en aurai l'occasion avant de modifier l'autre réponse.
T. Verron
@ T.Verron en revanche, l'autre solution suggérant d'utiliser le package plur. Il semble fonctionner dans cette situation sans problème.
Nom
J'ai changé la réponse acceptée dans l'autre question. En ce qui concerne Google, oui, j'ai moi aussi eu du mal à trouver des mots clés pour exprimer ce que j'essayais de faire. Et oui, les doublons sont bons! blog.stackoverflow.com/2010/11/…
T. Verron

Réponses:

11

Pour le cas interactif query-replace-regexp (CM-%) peut le faire, en utilisant le relativement inconnu \, pour le remplacement.

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

Si le texte de remplacement contient \, suivi d'une expression lisp, il utilise la valeur de cette expression comme remplacement. Dans ce cas, l'expression est un "si" qui prend une condition et la valeur de retour pour les cas vrai et faux.

Dans les commentaires, il est suggéré d'utiliser

\, (si \ 1 "chaîne2" "chaîne1")

Cela fonctionne car \ 1 sera "chaîne1" si le modèle correspond à chaîne1, et sera nul sinon. Lisp prend toute valeur non nulle comme vraie. Bien que cela fonctionne et soit plus court, je pense que ma réponse est plus utile. Je pense que le code est plus lisible pour quelqu'un dont les connaissances nettes sont limitées. Il a un deuxième avantage car il fonctionne toujours si le motif "de" est donné comme

\(string1\|string2\)

ou même

string1\|string2
icare
la source
2
Certains commentaires dans le candidat en double ont suggéré la syntaxe plus simple \,(if \1 "string2" "string1"), en utilisant l'expression rationnelle \(string1\)\|string2.
T. Verron
Voir les deux derniers paragraphes de (emacs) Regexp Replace.
Basil
-1

Eh bien, peut-être qu'avec une macro, ce serait facile:

F3C-saRETC-bM-tF4. L'utilisation de cette macro sur votre question crie ce résultat:

Je voudrais changer toutes les occurrences de la chaîne a (disons chaîne1) avec une autre chaîne (disons chaîne2) et vice-versa. Pour être précis, j'ai un long document et ces chaînes se produisent plusieurs fois. Ce que je fais actuellement, c'est de remplacer string1 -> string3, puis string2 -> string1 et enfin string3 -> string2.

Je me demande s'il y a déjà une fonction dans emacs qui fait ça. D'autres solutions sont les bienvenues.

Je transpose des positions entre n'importe quel mot après un aet ce mot. Vous pouvez ensuite modifier une telle macro pour transposer d'autres mots également sans avoir à redéfinir la macro entière, vous pouvez modifier la macro avec C-xC-kRET.

shackra
la source
1
Je ne pense pas que la question soit liée à la transposition des mots.
T. Verron
@ T.Verron C'est vrai, mais il veut une approche plus automatisée, semble-t-il.
shackra
1
Ce que fait votre macro, c'est d'échanger (transposer) chaque "a" avec le mot suivant. "une chaîne"> "chaîne a" etc. Ce qu'il veut faire, c'est par exemple remplacer chaque "a" par "le" et chaque "le" par "a".
T. Verron