2010-12-06 8 views

Antwort

15

Es gibt eine Bibliothek cl-ppcre genannt:

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

Installieren Sie es über quicklisp.

+0

Es sollte geläufig sein Lisp und ich möchte keine zusätzlichen Bibliotheken installieren. Ich habe nur SLIME. –

+0

Common Lisp enthält keine regulären Ausdrücke perl-compatibe, da sie Jahre später zu einem Standardmerkmal wurden. Eine einfache Implementierung von replace-string finden Sie hier: http://cl-cookbook.sourceforge.net/strings.html#manip – koddo

+0

Nützlicher Hinweis: Wenn Sie planen, einen Text durch Backslashes zu ersetzen, sollten Sie besser verwenden antworte unten. Ich habe versucht, es mit cl-ppcre zu ersetzen, aber es ist nicht einfach, so dass die Funktion unten besser für diesen Job geeignet war. – MatthewRock

5

Ich denke, es gibt keine solche Funktion in der Norm. Wenn Sie nicht über einen regulären Ausdruck (cl-ppcre) verwenden möchten, können Sie diese verwenden:

(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 wies darauf hin, dass dies nicht für den Ersatz nicht funktioniert, zB "\"" mit "\\\"" in "str\"ing". Da ich das jetzt betrachte oben als recht umständlich soll ich die Umsetzung in den Common Lisp Cookbook gegeben vorzuschlagen, die viel besser ist:

(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))) 

Ich mag besonders die Verwendung von with-output-to-string, die im Allgemeinen als concatenate besser abschneidet.

+0

Obwohl die letztere Implementierung hängt, wenn * part * die leere Zeichenfolge ist. Es sollte darauf achten, um richtig zu sein. –