2010-12-06 2 views
6

Есть ли какая-то функция, похожая на PHP str_replace в Lisp?str_replace в Лиспе?

http://php.net/manual/en/function.str-replace.php

+0

Дубликат http://stackoverflow.com/questions/90977/replace-char-in-emacs-lisp? – khachik 2010-12-06 13:08:32

+1

Он должен быть общим lisp, и я не хочу устанавливать какие-либо дополнительные библиотеки. У меня только SLIME. – 2010-12-06 14:04:41

+0

Если вы не хотите решения elisp, вы не должны отмечать вопрос elisp. – sepp2k 2010-12-06 23:21:22

ответ

15

Существует библиотека называется сл-ppcre:

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

Установите его с помощью quicklisp.

5

Я думаю, что нет такой функции в стандарте. Если вы не хотите использовать регулярное выражение (сл-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)))) 

EDIT: 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.

Смежные вопросы