Suchen / Ersetzen-ähnliche Funktion zum Austauschen von Text


12

Ich versuche häufig, zB foodurch barund barmit fooin einem Puffer zu ersetzen .

Die Art, wie ich es normalerweise mache, ist entweder:

  • 3 abfrage ersetzt: aaa -> @@@, bbb -> aaa,@@@ -> bbb
  • Geben Sie die Automatisierung auf und tauschen Sie sie einfach von Hand aus

Ich nehme an, dass es möglich ist, mithilfe der ,Syntax in etwas zum Funktionieren zu bringen, um query-replace-regexpzu testen, ob die übereinstimmende Zeichenfolge aaaoder ist bbb. Aber die resultierende Syntax wäre zu umständlich, so dass ich es nie wirklich ausprobiert habe.

Angesichts der Tatsache, wie häufig eine Aufgabe ist, muss es meiner Meinung nach eine bessere, einstufige Methode geben, die entweder integriert oder in ein vorhandenes Paket integriert ist. Gibt es?


Es mag einen einstufigen Weg geben, aber dein erster Weg ist nicht schlecht, IMO. Und wenn Sie die Ersetzungszeichenfolge richtig auswählen, können Sie für den zweiten Durchgang einfach keine Ersetzung abfragen.
Drew

@Drew Normalerweise query-replaceweiß ich, dass es normalerweise schneller geht, M-% str1 str2als den Punkt zu verschieben und die Änderung von Hand vorzunehmen . Es ist schön, weil ich keine Zeit damit verschwenden muss, darüber nachzudenken, was am schnellsten sein wird, auch wenn es nur ein einziges Mal vorkommt str1. Idealerweise möchte ich, dass die Textumkehrung genauso schnell erfolgt, damit ich sie verwenden kann, ohne auch darüber nachzudenken.
T. Verron

Jemand wird eine einfache Antwort geben. Sie können ohne Zweifel Ihre Anforderungen erfüllen, indem Sie beispielsweise einen Lisp-Ausdruck für die Ersetzung verwenden und auf den zu ersetzenden Text verweisen. Verwenden Sie z. B. etwas Ähnliches wie die Swap-Sprache (setq a (prog1 b (setq b a))). Und vielleicht gibt es sogar einen einfacheren Weg.
Drew

2
Ich finde das nicht \,(if \1 "b" "a")besonders hässlich (gegen einen Regexp von \(a\)\|b), aber trotzdem müssen die Wörter zweimal getippt werden, wenn dich das stört.
Politza

2
Warum nicht \(aaa\)\|bbb?
Politza

Antworten:


7

Hier ist ein kleiner Befehl, der dies erledigt:

(defun query-swap-strings (from-string to-string &optional delimited start end)
  "Swap occurrences of FROM-STRING and TO-STRING."
  (interactive
   (let ((common
          (query-replace-read-args
           (concat "Query swap"
                   (if current-prefix-arg
                       (if (eq current-prefix-arg '-) " backward" " word")
                     "")
                   (if (use-region-p) " in region" ""))
           nil)))
     (list (nth 0 common) (nth 1 common) (nth 2 common)
           (if (use-region-p) (region-beginning))
           (if (use-region-p) (region-end)))))
  (perform-replace
   (concat "\\(" (regexp-quote from-string) "\\)\\|" (regexp-quote to-string))
   `(replace-eval-replacement replace-quote (if (match-string 1) ,to-string ,from-string))
   t t delimited nil nil start end))

Danke, das ist weitaus aufwändiger als etwas, das ich selbst geschrieben hätte! Vielleicht könnten Sie die implementierten Funktionen näher erläutern? Ich sehe, dass Sie mit dem Präfix-Argument rückwärts gehen, dass es das Ersetzen nur in der Region ausführt, wenn es benötigt wird ... Oder ist es nur ein Umschreiben query-replacefür die Inversion, so dass es alle seine Funktionen beibehält? Es entspricht nicht 100% der Definition in meinem Emacs, aber ich bin immer noch mit 24,5 ...
T. Verron

@ T.Verron Dies ist nur ein Standardkörper aus query-replaceder Funktionsfamilie der neuesten Version, daher bleiben alle Funktionen erhalten. Am Ende der Funktion habe ich meine empfohlene Methode zum Austauschen von Strings hinzugefügt, die im Emacs-Handbuch erwähnt wird.
link0ff

Ich habe wahrscheinlich zu schnell akzeptiert. Die Funktion funktioniert hier nur (emacs 24.3) wenn ich auskommentiere backwardund region-noncontiguous-pvom aufruf bis perform-replace. Handelt es sich um ein allgemeines Problem, oder hat sich die Benutzeroberfläche perform-replacezwischen den Versionen geändert?
T. Verron

Ja, die Benutzeroberfläche wurde geändert, und diese beiden Argumente wurden in der neuesten Version hinzugefügt, sodass sie in früheren
Versionen

2
Diese Lösung scheint jetzt auch in Ordnung zu sein.
Name der

9

Installieren Sie plur

und führen Sie den Befehl aus plur-query-replace

und Eingabe {foo,bar}und deren Ersatz{bar,foo}

Klicken Sie yauf, um die gewünschten Vorkommen zu ersetzen.

Es gibt auch nicht interaktive und suchähnliche Varianten dieses Befehls.


Vielen Dank! plurs zweck ist auch etwas, wonach ich manchmal gesucht habe, ich werde es mir auf jeden fall ansehen. Mein einziges Zögern ergibt sich aus dem Kommentar des Autors des obigen Pakets ...;)
T. Verron

1
plurerfordert emacs 24.4.
T. Verron
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.