Shammer's Philosophy

My private adversaria

sbcl で文字列を扱う

Common Lisp と 日本語 と 文字コードが参考になった。ここのサイトの例をマネしてみたり、ちょっと自分でアレンジしていろいろやってみた結果。

UTF-8 の byte 配列を文字列にしてみる。

* (octets-to-string (concatenate '(vector (unsigned-byte 8)) #(65) #(65)) :external-format :UTF-8)

"AA"
*
* (sb-ext:octets-to-string (concatenate '(vector (unsigned-byte 8)) #(229) #(156) #(176) #(231) #(144) #(131)) :external-format :UTF-8)

"地球"
*

文字コードを任意のものにできるようにしてみる

* (defun make-encoding-pair (string-symbol encoding-parameter)
    (list :name string-symbol :value encoding-parameter))

MAKE-ENCODING-PAIR
* (defparameter *encode-table*
    (append (list (make-encoding-pair "UTF-8" ':UTF-8))
            (list (make-encoding-pair "EUC-JP" ':EUC-JP))))

*ENCODE-TABLE*
* (defun select-encoding (encode)
    (remove-if-not
      #'(lambda (element)
          (equal (getf element :name) encode))
    *encode-table*))

SELECT-ENCODING
* (defun select-encoding-value (encode)
    (nth 3 (car (select-encoding encode))))

SELECT-ENCODING-VALUE
* (select-encoding-value "UTF-8")

:UTF-8
* (select-encoding-value "EUC-JP")

:EUC-JP
* (octets-to-string (concatenate '(vector (unsigned-byte 8)) #(65) #(66) #(67)) :external-format (select-encoding-value "UTF-8"))

"ABC"
*

external-format の値に文字列を渡すことはできない。使用可能な文字コード一覧のテーブルから文字コードを取得して、external-format の引数として渡すようにしてみた。とりあえず UTF-8EUC-JP のみだけれども、*encode-table* の定義時に同じように追加すれば他の文字コードも使用できるようになる。

文字列をバイト配列に変換する

* (string-to-octets "Japanese" :external-format :UTF-8)

#(74 97 112 97 110 101 115 101)
* (string-to-octets "日本語" :external-format :UTF-8)

#(230 151 165 230 156 172 232 170 158)
*

難しいことは何もない。最初の逆のパターン。とりあえず、基本はこんなところだろうか。。。