Как заменить "(" на "\ (" в выражении регулярного выражения, Emacs / elisp? - PullRequest
2 голосов
/ 12 мая 2010

Вопрос в качестве заголовка.

Точнее говоря, я довольно устал от необходимости набирать \( и т. Д. Каждый раз, когда мне нужна скобка в (интерактивных) функциях регулярного выражения Emacs (не говоря уже о \\( в коде).Поэтому я написал что-то вроде

(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)))))

в надежде, что я смогу легко забыть об идиосинкразии emacs в регулярном выражении во время «режима взаимодействия».За исключением того, что я не могу получить правильное регулярное выражение ...

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

дает \\(abc вместо требуемого \(abc.Другие вариации по количеству слешей просто дают ошибки.Мысли?

С тех пор как я начал задавать вопросы, я мог бы также задать еще один: поскольку в коде lisp не предполагается использовать интерактивные функции, советовать query-replace-regexp должно быть в порядке, я прав?

1 Ответ

7 голосов
/ 12 мая 2010

Замена у вас хорошо работает для меня.

Возьми текст:

hi there mom
hi son!

и попробуйте query-replace-regexp с вашим советом:

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

выходы

hi mom!
hi son!

Мне не нужно было ставить обратную косую черту перед скобками, чтобы привести их в группу. Тем не менее, это отключает возможность совпадения с фактическими скобками ...

Причина, по которой replace-regexp-in-string приводит к \\(abc, заключается в том, что строка эквивалентна интерактивному типу \(abc. В строке \ используется для обозначения того, что следующий символ является специальным, например, "\t" - строка с вкладкой. Таким образом, чтобы указать только обратную косую черту, перед ней необходимо использовать обратную косую черту "\\" - строка, содержащая обратную косую черту.

Что касается рекомендаций по интерактивным функциям, код lisp может вызывать интерактивные функции по своему усмотрению. Ярким примером является find-file - который вызывается повсюду. Чтобы сделать ваш совет немного более безопасным, вы можете обернуть тело чеком на interactive-p, чтобы избежать путаницы при внутренних вызовах:

(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)))))
...