Common Lisp中的str_replace是什么?

9

这是一个关于在Emacs Lisp中替换字符的问题,重复了Stack Overflow上的一个帖子。 - khachik
3
它应该使用Common Lisp编写,我不想安装任何额外的库,我只有SLIME。 - Richard Knop
如果您不想要elisp解决方案,就不应该使用elisp标签来提问。 - sepp2k
你说的Lisp是什么意思?我从下面的评论中了解到你指的是CL。你应该一开始就这样说。 - Tagore Smith
3个回答

21

有一个名为cl-ppcre的库:

(cl-ppcre:regex-replace-all "qwer" "something to qwer" "replace")
; "something to replace"

通过quicklisp进行安装。


1
它应该使用Common Lisp编写,我不想安装任何额外的库,我只有SLIME。 - Richard Knop
1
Common Lisp没有包含Perl兼容的正则表达式,因为它们是多年后成为标准功能的。您可以在此处找到replace-string的简单实现:http://cl-cookbook.sourceforge.net/strings.html#manip - koddo
有用的提示:如果您打算用反斜杠替换一些文本,最好使用下面的答案。我尝试使用cl-ppcre进行替换,但这并不容易,所以实际上下面的函数更适合这项工作。 - MatthewRock

8

我认为标准库中没有这样的函数。如果不想使用正则表达式(cl-ppcre),可以使用以下代码:

(defun string-replace (search replace string &optional count)
  (loop for start = (search search (or result string)
                            :start2 (if start (1+ start) 0))
        while (and start
                   (or (null count) (> count 0)))
        for result = (concatenate 'string
                                  (subseq (or result string) 0 start)
                                  replace
                                  (subseq (or result string)
                                          (+ start (length search))))
        do (when count (decf count))
        finally (return-from string-replace (or result string))))

编辑:Shin Aoyama指出,这种方法无法替换例如在"str\"ing"中将"\""替换为"\\\""的情况。因为我现在认为上面的方法相当繁琐,所以我应该提议在Common Lisp Cookbook中给出的实现,它更好:

(defun replace-all (string part replacement &key (test #'char=))
  "Returns a new string in which all the occurences of the part 
is replaced with replacement."
  (with-output-to-string (out)
    (loop with part-length = (length part)
          for old-pos = 0 then (+ pos part-length)
          for pos = (search part string
                            :start2 old-pos
                            :test test)
          do (write-string string out
                           :start old-pos
                           :end (or pos (length string)))
          when pos do (write-string replacement out)
          while pos)))

我特别喜欢使用with-output-to-string,它通常比concatenate表现更好。


虽然后一种实现在part为空字符串时会出现卡住的情况,但它应该进行检查以确保正确性。 - Diogo Franco

7
如果替换的只是一个字符,这通常是情况,您可以使用substitute函数:
(substitute #\+ #\Space "a simple example") => "a+simple+example"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接