如何用lisp替换文件中的字符串?
用lisp替换文件中的字符串的方法是什么 有一个文件由如何用lisp替换文件中的字符串?,lisp,replace,Lisp,Replace,用lisp替换文件中的字符串的方法是什么 有一个文件由*文件路径*标识,一个搜索字符串*搜索词*和一个替换字符串*替换词*标识 如何使所有*搜索项*s的实例替换为*替换项*s而生成文件,最好是替换旧文件?可以通过多种方式实现,例如使用正则表达式。我看到的最独立的方式如下所示: (defun replace-in-file (search-term file-path replace-term) (let ((contents (rutil:read-file file-path)))
*文件路径*
标识,一个搜索字符串*搜索词*
和一个替换字符串*替换词*
标识
如何使所有
*搜索项*
s的实例替换为*替换项*
s而生成文件,最好是替换旧文件?可以通过多种方式实现,例如使用正则表达式。我看到的最独立的方式如下所示:
(defun replace-in-file (search-term file-path replace-term)
(let ((contents (rutil:read-file file-path)))
(with-open-file (out file-path :direction :output :if-exists :supersede)
(do* ((start 0 (+ pos (length search-term)))
(pos (search search-term contents)
(search search-term contents :start2 start)))
((null pos) (write-string (subseq contents start) out))
(format out "~A~A" (subseq contents start pos) replace-term))))
(values))
请参见rutil:read file
的实现:
另外请注意,此函数将用任何字符替换搜索词,包括换行符。在带有ireggex egg的chicken scheme中:
(use irregex) ; irregex, the regular expression library, is one of the
; libraries included with CHICKEN.
(define (process-line line re rplc)
(irregex-replace/all re line rplc))
(define (quickrep re rplc)
(let ((line (read-line)))
(if (not (eof-object? line))
(begin
(display (process-line line re rplc))
(newline)
(quickrep re rplc)))))
(define (main args)
(quickrep (irregex (car args)) (cadr args)))
编辑:在上面的示例中,缓冲输入不允许regexp跨越
许多行。为了解决这个问题,这里有一个更简单的实现,它将整个文件扫描为一个字符串:
(use ireggex)
(use utils)
(define (process-line line re rplc)
(irregex-replace/all re line rplc))
(define (quickrep re rplc file)
(let ((line (read-all file)))
(display (process-line line re rplc))))
(define (main args)
(quickrep (irregex (car args)) (cadr args) (caddr args)))
还有一个问题需要解决,但首先警告很少:
处理程序案例中
,并处理各种错误,如磁盘空间不足、设备未就绪、读/写权限不足、缓冲区内存分配不足等(defun file-replace-string (search-for replace-with file
&key (element-type 'base-char)
(temp-suffix ".tmp"))
(with-open-file (open-stream
file
:direction :input
:if-exists :supersede
:element-type element-type)
(with-open-file (temp-stream
(concatenate 'string file temp-suffix)
:direction :output
:element-type element-type)
(do ((buffer (make-string (length search-for)))
(buffer-fill-pointer 0)
(next-matching-char (aref search-for 0))
(in-char (read-char open-stream nil :eof)
(read-char open-stream nil :eof)))
((eql in-char :eof)
(when (/= 0 buffer-fill-pointer)
(dotimes (i buffer-fill-pointer)
(write-char (aref buffer i) temp-stream))))
(if (char= in-char next-matching-char)
(progn
(setf (aref buffer buffer-fill-pointer) in-char
buffer-fill-pointer (1+ buffer-fill-pointer))
(when (= buffer-fill-pointer (length search-for))
(dotimes (i (length replace-with))
(write-char (aref replace-with i) temp-stream))
(setf buffer-fill-pointer 0)))
(progn
(dotimes (i buffer-fill-pointer)
(write-char (aref buffer i) temp-stream))
(write-char in-char temp-stream)
(setf buffer-fill-pointer 0)))
(setf next-matching-char (aref search-for buffer-fill-pointer)))))
(delete-file file)
(rename-file (concatenate 'string file temp-suffix) file))