How to replace “(” with “\(” in the regexp, Emacs/elisp flavor?

和自甴很熟 提交于 2019-12-12 19:15:29

问题


Question as title.

More specifically, I'm rather tired of having to type \(, etc. every time I want a parenthesis in Emacs's (interactive) regexp functions (not to mention the \\( in code). So I wrote something like

(defadvice query-replace-regexp (before my-query-replace-regexp activate)
   (ad-set-arg 0 (replace-regexp-in-string "(" "\\\\(" (ad-get-arg 0)))
   (ad-set-arg 0 (replace-regexp-in-string ")" "\\\\)" (ad-get-arg 0)))))

in hope that I can conveniently forget about emacs's idiosyncrasy in regexp during "interaction mode". Except I cannot get the regexp right...

(replace-regexp-in-string "(" "\\\\(" "(abc")

gives \\(abc instead of the wanted \(abc. Other variations on the number of slashes just gives errors. Thoughts?

Since I started questioning, might as well ask another one: since lisp code is not supposed to use interactive functions, advicing query-replace-regexp should be okay, am I correct?


回答1:


The replacement you has works well for me.

Take the text:

hi there mom
hi son!

and try query-replace-regexp with your advice:

M-x query-replace-regexp (hi).*(mom) RET \1 \2! RET

yields

hi mom!
hi son!

I didn't have to put a backslash in front of the parentheses to get them to group. That said, this disables being able to match actual parentheses...

The reason the replace-regexp-in-string yields \\(abc, is that as a string, that is equivalent to an interactively typed \(abc. In a string \ is used to denote that the following character is special, e.g. "\t" is a string with a tab. So, in order to specify just a backslash, you need to use a backslash in front of it "\\" is a string containing a backslash.

Regarding advising interactive functions, lisp code can call interactive functions all it wants. A prime example is find-file - which is called all over the place. To make your advice a little safer, you can wrap the body with a check for interactive-p to avoid mussing with internal calls:

(defadvice query-replace-regexp (before my-query-replace-regexp activate)
  (when (interactive-p)
    (ad-set-arg 0 (replace-regexp-in-string "(" "\\\\(" (ad-get-arg 0)))
    (ad-set-arg 0 (replace-regexp-in-string ")" "\\\\)" (ad-get-arg 0)))))


来源:https://stackoverflow.com/questions/2815903/how-to-replace-with-in-the-regexp-emacs-elisp-flavor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!