なんだこれは

はてなダイアリーから移転しました。

guess というライブラリをみつけた

https://github.com/zqwell/guess にあるライブラリだ。

書いてあるとおりにやってみよう。ただし、ClozureCLで。

環境

Mac OS X
Clozure CL
quicklisp

1. quicklisp のパスのあるフォルダ に git cloneする。

cd ~/quicklisp/local-projects/
git clone git://github.com/zqwell/guess.git

2. quicklisp で guess を読みこむ

(ql:quickload :guess)

これでうまく読みこめた。

3. 日本語を バイナリのvectorにして、文字コードを判定してみよう。

string-to-octetsは ClozureCL にないので、マニュアルを読むと、encode-string-to-octets とある。external-formatで指定しているので微妙におもえるかもしれないがこれで判定できている。

(encode-string-to-octets
    "こんばんわ"
    :external-format
        (make-external-format
            :character-encoding :utf-8
            :line-termination :unix))
;-> #(227 129 147 227 130 147 227 129 176 227 130 147 227 130 143)
;-> 15
(guess:CES-GUESS-FROM-VECTOR
     (encode-string-to-octets
         "こんばんわ"
         :external-format (make-external-format :character-encoding :utf-8
                                                :line-termination :unix)) :jp )
;-> :UTF-8

いろいろ遊ぶ

UTF-8以外でもいける

(guess:CES-GUESS-FROM-VECTOR
    (encode-string-to-octets
        "こんばんわ"
        :external-format (make-external-format :character-encoding :euc-jp
                                               :line-termination :unix)) :jp )
;-> :EUC-JP

EUC-JPは中国環境ではEUC-CNと思いきや?

(guess:CES-GUESS-FROM-VECTOR
    (encode-string-to-octets
        "こんばんわ"
        :external-format (make-external-format :character-encoding :euc-jp
                                               :line-termination :unix)) :cn )
;-> :GB2312

UTF-8は中国環境でもUTF-8?

(guess:CES-GUESS-FROM-VECTOR
    (encode-string-to-octets
        "こんばんわ"
        :external-format (make-external-format :character-encoding :utf-8
                                               :line-termination :unix)) :cn )
;-> :UTF-8

4. ファイルを vector にして文字コードを判定する

(defun file-to-vector (name)
  (with-open-file (s name :direction :input :element-type '(unsigned-byte 8))
    (let ((buf (make-array (file-length s) :element-type '(unsigned-byte 8))))
      (read-sequence buf s)
      buf)))

(defun guess-file-encode (name &optional (scheme :jp) )
  (guess:CES-GUESS-FROM-VECTOR (file-to-vector name ) scheme ))

(defun guess-external-format (name &optional (scheme :jp) (line-termination :unix) )
  (make-external-format 
   :character-encoding (guess-file-encode name scheme)
   :line-termination line-termination))

これで (guess-file-encode "foo.csv")で文字コードが返ってくるので、with-open-file に文字コードを指定できる。