excel替换字符串中的某个字符_Emacs Hack - 批量替换字符串

026b68675f5e8b5e6ac341a9bdd7d7e3.png

实际问题

不使用interactive function(M-%)如何批量替换文件中的字符串?

解决思路

字符串替换分三种情况:

  1. 在当前buffer替换
  2. 在指定文件中替换
  3. 为指定目录下所有文件替换。

用于替换的pair有两种来源:

  1. repl-string-listrepl-regexp-list 变量
  2. repl-file 对应的文件。

字符串查找的方式有两种,分别对应两个函数:

  1. 纯字符串 (replall-string)
  2. 正则表达式 (replall-regexp)

优先使用列表变量的值,如果该变量值为nil则使用repl-file对应的文件中的值。其中文件中的pair只能用于 replall-string 函数。两个变量列表的值分别对应两个函数。repl-file的格式为每行一个pair,分别为被替换的字符串和用于替换的字符串,用空格隔开。

代码实现

主函数 replall-stringreplall-regexp 可以选择替换类型。对于具体的情况也可以直接使用具体的替换函数。代码如下:

(setq repl-string-list
      '(("old" "new")
        ("test" "测试")
        ("错误" "right")
        ("隔开你" "戈楷旎")))

(setq repl-regexp-list
      '(("." "。")))

(setq repl-file "~/replace.txt")

(defun replall--read-pair-from-file ()
  (let ((repl-list '()))
    (with-temp-buffer
      (insert-file-contents repl-file)
      (goto-char (point-min))
      (while (< (point) (point-max))
        (setq repl-pair (split-string (thing-at-point 'line) "[ ftnrv]+" t "[ ftnrv]+"))
        (if (null repl-pair)
            (next-line)
          (next-line)
          (setq repl-list (append repl-list (list repl-pair))))))
    repl-list))

(defun replall--get-repl-string-list ()
  (if (bound-and-true-p repl-string-list)
      repl-string-list
    (replall--read-pair-from-file)))

(defun replall--get-repl-regexp-list ()
  (if (bound-and-true-p repl-regexp-list)
      repl-regexp-list
    (message "please set variable 'repl-regexp-list'!")))

(defun replall--string (file lst)
  (with-temp-buffer
    (insert-file-contents file)
    (goto-char (point-min))
    (dolist (pair lst)
      (while (search-forward (car pair) nil t)
        (replace-match (cadr pair)))
      (goto-char (point-min)))
    (write-file file)))

(defun replall--regexp (file lst)
  (with-temp-buffer
    (insert-file-contents file)
    (goto-char (point-min))
    (dolist (pair lst)
      (while (re-search-forward (car pair) nil t)
        (replace-match (cadr pair)))
      (goto-char (point-min)))
    (write-file file)))

(defun replall-string-in-curr-buffer ()
  (interactive)
  (let ((curr-file (buffer-file-name (current-buffer)))
        (repl-list (replall--get-repl-string-list)))
    (replall--string curr-file repl-list)))

(defun replall-regexp-in-curr-buffer ()
  (interactive)
  (let ((curr-file (buffer-file-name (current-buffer)))
        (repl-list (replall--get-repl-regexp-list)))
    (replall--regexp curr-file repl-list)))

(defun replall-string-in-file (file repl)
  (interactive "fchoose a file to be processed: ")
  (let ((repl-list (replall--get-repl-string-list)))
    (replall--string file repl-list)))

(defun replall-regexp-in-file (file repl)
  (interactive "fchoose a file to be processed: ")
  (let ((repl-list (replall--get-repl-regexp-list)))
    (replall--regexp file repl-list)))

(defun replall--get-real-files-in-dir (dir)
  (let ((real-files)
        (files (directory-files dir)))
    (dolist (file files)
      (when (not (or (string= "." (substring file 0 1))
                     (string= "#" (substring file 0 1))
                     (string= "~" (substring file -1))))
    (push file real-files)))
    real-files))

(defun replall-string-in-directory (dir)
  (interactive "Dchoose a directory to be processed: ")
  (let* ((repl-list (replall--get-repl-string-list))
         (real-files (replall--get-real-files-in-dir dir)))
    (dolist (file real-files)
      (replall--string (concat dir file) repl-list))))

(defun replall-regexp-in-directory (dir)
  (interactive "Dchoose a directory to be processed: ")
  (let* ((repl-list (replall--get-repl-regexp-list))
         (real-files (replall--get-real-files-in-dir dir)))
    (dolist (file real-files)
      (replall--regexp (concat dir file) repl-list))))

(defun replall-string (type)
  (interactive "sreplace string: 1.in current buffer  2.in a file  3.in a directory (input 1~3): ")
  (cond
   ((string= type "1")
    (replall-string-in-curr-buffer))
   ((string= type "2")
    (call-interactively #'replall-string-in-file))
   ((string= type "3")
    (call-interactively #'replall-string-in-directory))
   (t (message "please input 1~3!"))))

(defun replall-regexp (type)
  (interactive "sreplace regexp: 1.in current buffer  2.in a file  3.in a directory (input 1~3): ")
  (cond
   ((string= type "1")
    (replall-regexp-in-curr-buffer))
   ((string= type "2")
    (call-interactively #'replall-regexp-in-file))
   ((string= type "3")
    (call-interactively #'replall-regexp-in-directory))
   (t (message "please input 1~3!"))))
原文地址:
Emacs Hack - 批量替换字符串​geekinney.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值