Is there some function similar to PHP's str_replace in Common Lisp?
str_replace in Common Lisp?
Asked Answered
Duplicate of https://mcmap.net/q/1169904/-replace-char-in-emacs-lisp ? –
Builtup
It should be in common lisp and I don't want to install any additional libraries. I just have SLIME. –
Satterlee
If you don't want elisp solutions, you shouldn't tag the question with elisp. –
Preemie
What do you mean by Lisp? I gather from the comments below that you mean CL. You should say that in the first place. –
Scanlan
There is a library called cl-ppcre:
(cl-ppcre:regex-replace-all "qwer" "something to qwer" "replace")
; "something to replace"
Install it via quicklisp.
It should be in common lisp and I don't want to install any additional libraries. I just have SLIME. –
Satterlee
Common lisp doesn't include perl-compatibe regular expressions because they became a standard feature years later. You can find a simple implementation of replace-string here: cl-cookbook.sourceforge.net/strings.html#manip –
Francesco
Useful note: if you're planning on replacing some text with backslashes, you'd better use answer below. I've tried replacing it with cl-ppcre, but it isn't straightforward, so actually function below was better suited for this job. –
Baillieu
I think there is no such function in the standard. If you do not want to use a regular expression (cl-ppcre), you could use this:
(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))))
EDIT: Shin Aoyama pointed out that this does not work for replacing, e.g., "\""
with "\\\""
in "str\"ing"
. Since I now regard the above as rather cumbersome I should propose the implementation given in the Common Lisp Cookbook, which is much better:
(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)))
I especially like the use of with-output-to-string
, which generally performs better than concatenate
.
Although the latter implementation hangs if part is the empty string. It should check for it, to be correct. –
Kristankriste
If the replacement is only one character, which is often the case, you can use substitute:
(substitute #\+ #\Space "a simple example") => "a+simple+example"
© 2022 - 2024 — McMap. All rights reserved.