2012-01-30 44 views
5

我想將字符串轉換爲列表。例如,http =>(h t t p)。字符串列表中沒有#共同lisp

我嘗試:

(defun string-to-list (s) 
    (assert (stringp s) (s) "~s :questa non e una stringa") 
    (coerce s 'list)) 

,但如果我這樣做

(string-to-list "http") 

結果:

(#\h #\t #\t #\p). 

我可以刪除#\? 在此先感謝:)

回答

16

你爲什麼要那樣做?你所要求的是將一個字符串(一維字符數組)分成一系列符號。你真的想要嗎?

#\h是打印的字符對象。

您可以採用不同打印出來:

CL-USER 8 > (prinC#\h) 
h 

CL-USER 9 > (prin1 #\h) 
#\h 

讓我們使用PRINC打印清單:

CL-USER 10 > (map nil #'princ (coerce "Hello!" 'list)) 
Hello! 

順便說一句,因爲字符串,向量和列表的順序,你可以通過字符串直接映射...

CL-USER 11 > (map nil #'princ "Hello!") 
Hello! 
3

您可以用intern將字符串變成符號。你可以用string將一個字符變成一個字符串。實例化小寫字符串可能會導致它被打印爲|h|而不是h,因此您需要string-upcase它。把所有這些放在一起給出:

(loop for c in (coerce "http" 'list) 
     collecting (intern (string-upcase (string c)))) 
+0

謝謝!所以沒有辦法導致(h t t p)而不是(H T t P)? – r1si 2012-01-30 16:38:57

+0

@ r1si:我正在演示一種方法來解決這個問題。我會使用該評論,但它們對多行代碼示例不利。 – 2012-01-30 18:39:19

3

擴展larsmans的答案,你可以打印羅wercase符號不帶引號的,如果你改變了readtable:

(let ((*readtable* (copy-readtable))) 
    (setf (readtable-case *readtable*) :preserve) 
    (prin1 (loop for c in (coerce "http" 'list) 
       collecting (intern (string c))))) 

這將打印(h t t p)並返回(|h| |t| |t| |p|)

3

您可以打印未轉義的字符。查看變量*PRINT-ESCAPE*

功能WRITE具有關鍵字參數:ESCAPE爲:

(defun string-to-list (s) 
    (assert (stringp s) (s) "~s :questa non e una stringa") 
    (write (coerce s 'list) :escape nil) 


CL-USER 11 > (string-to-list "abcd") 
(a b c d) 
(#\a #\b #\C#\d) 

在上面的例子中被印刷在第一形式通過調用WRITE,所述第二形式是由REPL印刷的返回值。

+1

只用'princ'打印整個列表也會打印未轉義的元素。 – 2012-01-31 15:48:45