regexpパッケージで日本語を

概要

regexpパッケージで日本語を使う場合は、regexp:match-stringを使わずに自分で書きましょう
そうしないと、うまく文字列を切り出す事ができません。

;; バイト単位のsebseq(utf-8限定)
(defun subseq-byte(str from &optional to)
  (ext:convert-string-from-bytes
   (subseq 
     (ext:convert-string-to-bytes str charset:utf-8) from to)
   charset:utf-8))

;; regexp:match-stringの日本語版
(defun match-string-jp(str match)
  (subseq-byte str
               (regexp:match-start match)
               (regexp:match-end match)))

原因

  • clispは基本的にUTF-8で処理する。つまり文字列のインデックスは文字単位
  • regexpパッケージの返り値はバイト単位

つまり

(char "あa" 1) ; => #\a
(regexp:match "a" "あa")  ; => #S(REGEXP:MATCH :START 3 :END 4)

ということ。

解決策

しょうがないので、clispの独自拡張であるext:encodingモジュールをつかっていったんバイト配列に変換してから切り出すようにした。
めっさ効率悪い気がする。でもまあ、とりあえずはこれでいいや。
本当はUTF-8対応の正規表現ライブラリを使うのがスマートなんだろうなぁ。