5 votes

Emacs : remplacement d'expressions régulières pour changer la casse (dans scripts)

Ceci est lié à Emacs : remplacement d'expressions régulières pour changer la casse

Mon problème supplémentaire est que je dois script la recherche-remplacement, mais la fonction "\,()" la solution ne fonctionne (pour moi) que lorsqu'elle est utilisée de manière interactive (emacs 24.2.1) . A l'intérieur d'un script il donne l'erreur : "Invalid use of \' dans le texte de remplacement".

J'écris généralement un "perform-replace" dans un fichier qui sera chargé en cas de besoin. Quelque chose comme :

(effectuer-remplacer "<\\([^>]+\\)>" "<\\,(downcase \1)>" t t nil 1 nil (point-min) (point-max))

Il devrait être possible d'appeler une fonction pour générer le remplacement (pg 741 of the emacs lisp manual) J'ai essayé de nombreuses variantes de ce qui suit, mais sans succès :

(defun myfun ()
    (downcase (match-string 0)))

(perform-replace "..." (myfun . ()) t t nil)

Quelqu'un peut-il nous aider ?

3voto

Francesco Points 5760

Des constructions telles que \,() ne sont autorisées que dans les appels interactifs à query-replace c'est pourquoi Emacs se plaint dans votre cas.

La documentation de perform-replace indique qu'il ne faut pas l'utiliser dans le code elisp et propose une meilleure alternative, sur laquelle nous pouvons construire le code suivant :

(while (re-search-forward "<\\([^>]+\\)>" nil t)
  (replace-match (downcase (match-string 0)) t nil))

Si vous souhaitez toujours interroger l'utilisateur de manière interactive sur les remplacements, utilisez la fonction perform-replace comme vous l'avez fait est probablement la bonne chose à faire. Il y avait plusieurs problèmes dans votre code :

  1. Comme indiqué dans le manuel elisp la fonction de remplacement doit prendre deux arguments (les données que vous fournissez dans la cellule cons et le nombre de remplacements déjà effectués).

  2. Comme indiqué dans la documentation de query-replace-regexp (ou le manuel elisp ), vous devez vous assurer que case-fold-search o case-replace est fixé à nil afin que le modèle de cas ne soit pas transféré au remplaçant.

  3. Vous devez citer la cellule cons (myfun . nil) sinon elle sera interprétée comme un appel de fonction et évaluée trop tôt.

Voici une version fonctionnelle :

(let ((case-fold-search nil))
  (perform-replace "<\\([^>]+\\)>"
                   `(,(lambda (data count)
                       (downcase (match-string 0))))
                   t t nil))

2voto

Stefan Points 13308

C-h f perform-replace dit :

Don't use this in your own program unless you want to query and set the mark
just as `query-replace' does.  Instead, write a simple loop like this:

  (while (re-search-forward "foo[ \t]+bar" nil t)
    (replace-match "foobar"))

Aujourd'hui, le "<\\,(downcase \1)>" doit être remplacée par une expression Elisp qui construit la bonne chaîne de caractères, telle que (format "<%s>" (downcase (match-string 1))) .

Si vous avez besoin de la requête et des autres éléments, vous pouvez essayer : C-M-% f\(o\)o RET bar \,(downcase \1) baz RET et ensuite C-x RET RET pour voir quels arguments ont été construits lors de l'appel interactif.

Vous verrez la découverte (encore mieux si vous cliquez sur replace.el en C-h f perform-replace pour voir le code source de la fonction), que les replacements L'argument peut prendre la forme (FONCTION . ARGUMENT). Plus précisément, le code comporte un commentaire donnant quelques précisions :

;; REPLACEMENTS is either a string, a list of strings, or a cons cell
;; containing a function and its first argument.  The function is
;; called to generate each replacement like this:
;;   (funcall (car replacements) (cdr replacements) replace-count)
;; It must return a string.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X