2010-12-06 7 views

Respuesta

15

Hay una biblioteca llamada CL-ppcre:

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

instalarlo a través de quicklisp.

+0

Debería estar en lisp común y no quiero instalar ninguna biblioteca adicional. Solo tengo SLIME. –

+0

El lisp común no incluye las expresiones regulares de perl-compatibe porque se convirtieron en una característica estándar años después. Puede encontrar una implementación simple de replace-string aquí: http://cl-cookbook.sourceforge.net/strings.html#manip – koddo

+0

Nota útil: si está planeando reemplazar texto con barras diagonales inversas, será mejor que use Responda abajo. He intentado reemplazarlo con cl-ppcre, pero no es sencillo, así que en realidad la función de abajo era más adecuada para este trabajo. – MatthewRock

5

Creo que no hay tal función en el estándar. Si no desea utilizar una expresión regular (CL-ppcre), se puede usar esto:

(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 señaló que esto no funciona para la sustitución, por ejemplo, "\"" con "\\\"" en "str\"ing". Ya que ahora considero que lo anterior como bastante engorroso que debería proponer la implementación dada en el Common Lisp Cookbook, lo cual es mucho mejor:

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

me gusta especialmente el uso de with-output-to-string, que generalmente funciona mejor que concatenate.

+0

Aunque la última implementación se bloquea si * parte * es la cadena vacía. Debería verificarlo, para ser correcto. –