我写了一个小函数帮助我替换字符。 我想达到的效果是把
something sl a link sl something
转换成
something [[a link][a link]] something
也就是说把sl
之间的字符替换到[[%s][%s]]
的效果。
我的实现是这样的
(defvar short-finger-replace-book-for-org '(("sl" "sl" "[[%s][%s]]"))
"a list of cons of (key . replacement) for replacing in org mode.
In replacement, use `format' compatible %-sequnce regarding surrounded text
as substitute.
For example (\"sc\" . \"```%s```\") replace
\" sc some code sc\" into \"```some code```\".")
;; something sl some sl something
(setq short-finger-replace-book-for-org '(("sl" "sl" " [[%s][%s]] ")))
(defvar short-finger-active-book ()
"Current used short-finger-replace-book.")
(setq short-finger-active-book short-finger-replace-book-for-org)
(defun short-finger-format-line ()
(interactive)
(dolist (key-replace-con short-finger-active-book)
(let ((match-str ; the pattern we are going to replace
(format "[ \n]%s .+? %s[ \n]"
(nth 0 key-replace-con)
(nth 1 key-replace-con))))
(move-beginning-of-line nil) ; to search whole line
(while (re-search-forward match-str (line-end-position) t)
(message (format "%d" (point)))
(message (match-string-no-properties 0))
(replace-match
(multi-format ; replace match-string with replace string :P
(nth 2 key-replace-con)
(short-finger--extract-middle (match-string-no-properties 0) key-replace-con))
nil t)))))
(defun test-replace ()
(interactive)
(re-search-forward "[ \n]sl .+? sl[ \n]" (line-end-position))
(replace-match " [[some][some]] "))
(defun short-finger--extract-middle (string key-replace-con)
(let ((front-regex (format "^[ \n]%s " (car key-replace-con)))
(end-regex (format " %s[ \n]$" (nth 1 key-replace-con))))
(replace-regexp-in-string
front-regex ""
(replace-regexp-in-string
end-regex "" string))))
(defun multi-format (string replacement)
"Replace one string multiple times.
E.g:
(multi-format \"something %s %s\" \"haha\")
=> \"something haha haha\""
(let ((element-list (split-string string "%s"))
(return-list ()))
(dolist (element element-list)
(setq return-list (append return-list (list element replacement))))
(setq return-list (nbutlast return-list))
(apply #'concat return-list)))
然而运行函数是这样的
(如果gif链接失效的话,情况基本就是我在下面那行注释上运行函数,函数在第三行莫名插入替换字符)
这是什么鬼啊?
我测试过了所有的子函数,测试函数test-replace
也没问题,edebug一步一步走会在replace-match
莫名跳到第三行……
求大神指教
谢谢大家
问题的直接原因似乎是没有使用save-match-data
,@twlz0ne 给出了更好地实现,避免了很多问题。