如何替换 slash (/) ?

我想要把 / 替换成 \/ ,就只是文字上的替换,这样做

(replace-regexp-in-string "/" "\\/" (regexp-quote "fdsf/fsf") t t)

只能替换成 \\/ ,求教如何实现?

\/ 这两个字符用 Emacs Lisp String 写成 "\\/",就好像假如你想表示 \n 这两个字符(而不是一个换行字符),得写成 "\\n" 一样。

22 AM

所以你方法已经得到了正确的结果,为了让你的方法看起来更清楚一点,再举个例子:

(replace-regexp-in-string "/" "\\\\/" "foo/bar")
;; => "foo\\/bar"

(replace-regexp-in-string "/" "\\/" "foo/bar" nil 'literal)
;; => "foo\\/bar"

哦哦,我是想替换成foo\/bar,该怎么办。

你的描述不清楚,能不能看下 Markdown 渲染出来的效果?另外句号一个就够了,否则我不明白连用一个、二个、三个是什么区别。

我的问题,修改好了

你这条语句返回的就是 \/,只不过表示为字符串的时候转意成了 \\/

#+BEGIN_SRC emacs-lisp :results value raw
(replace-regexp-in-string "/" "\\/" (regexp-quote "fdsf/fsf") t t)
#+END_SRC

#+RESULTS:
fdsf\/fsf
#+BEGIN_SRC emacs-lisp :results value code
(replace-regexp-in-string "/" "\\/" (regexp-quote "fdsf/fsf") t t)
#+END_SRC

#+RESULTS:
#+BEGIN_SRC emacs-lisp
"fdsf\\/fsf"
#+END_SRC

有办法选择输出的结果是raw吗?这个是用在vim ex里面,如果是\\/就没法使用了。

函数如下:

(defun evil-quick-replace (beg end)
  (interactive "r")
  (when (evil-visual-state-p)
    (evil-exit-visual-state)
    (let ((selection (regexp-quote (buffer-substring-no-properties beg end))))
      (setq command-string (format "1,$s /%s/%s/g" selection selection))
      (minibuffer-with-setup-hook
          (lambda () (backward-char 2))
        (evil-ex command-string)))))

这里的selection,如果选择的区域是foo/bar,那么转换出来就变成了foo\\/bar无法match,必须要foo\/bar才行。

  • 没看懂你这个函数的作用。两个 selection 又是为什么。
  • 也没看懂你的描述。我觉得你不如用截图来说明。

说个题外的:如果 pattern 中包含 /,为了避免转移符号的干扰,表达式可以这样写:s!pat/tern!replace/ment!g

谢谢啊。这个函数就是用来在evil-mode下快速替换的。

先选择一块编辑区域,然后调用这个函数。

换成!还是有一样的问题,对selection中有/的是没问题了,但是对有!还是有一样的问题。 40

所以要想正确的在evil ex下match选中的区域,必须要在/前加一个\,两个的话就变成\\/,并不能match选择区域的/了,对!也是一样的。

不知道解释清楚了没。:disappointed_relieved:

还是很懵。

回到主题:

(replace-regexp-in-string "/" "\\/" (regexp-quote "foo/bar") t t) 已经做到了,只是它表示为 Emacs Lisp String 的时候是 \\/,不明白纠结点在哪里?

evil-ex--replace-slash

如果你想的是,写正则表达式的时候偷点懒,表达式只写 \/ 但是却希望它匹配内容 \/,那么必须自行处理:

  • 方式1: 自己处理用户输入(用自己的方式写正则),回车确认,转为正规的正则表达式,交给 evil 执行。这么做就得自己实现类似 evil 的预览了。
  • 方式2: 改造 evil-ex, 让它 minibuffer 输入(或显示)的是 \/,背后真正使用的是 \\/
  1. 选择区域foo/bar
  2. 调用函数evil-quick-replace 并不匹配选择的区域foo/bar
  3. 需要在/前添加\

而如果按照之前说的(replace-regexp-in-string "/" "\\/" (regexp-quote "fdsf/fsf") t t)

那么得到的效果是,并不能匹配到之前选择的区域

最后一幅图正则表达式多了一个 \,你可能 replace-regexp-in-string 放错了位置,仔细看下我的:

evil-ex--replace-slash-2

1 个赞

原来如此,是被regexp-quote这个函数影响了。谢谢了:+1: