2008年9月19日金曜日

文字列を分割する

NANRIさんとこのコードを参考にsplit-stringを繰り返しでやってみた。

# position関数内の:test関数の挙動がよく分かってませんが


(defun split-string (string &optional (separator #\space)
                            omit-nulls)
  (labels ((pos (str sep)
             (position sep str
                       :test #'(lambda (x y)
                                 (find y x :test #'char=)))))
    (let ((sep (string separator))
          (acc '()))
      (do* ((str string (subseq str (1+ n)))
            (n (pos str sep) (pos str sep)))
           ((null n)
            (nreverse (if omit-nulls
                          `(,str ,@acc)
                        (remove "" `(,str ,@acc)
                                :test #'string=))))
        (push (subseq str 0 n) acc)))))

(split-string "C:/home/xyzzy/xyzzy.exe" #\/)
=>("C:" "home" "xyzzy" "xyzzy.exe")
(split-string "system::typespec-alist" #\:)
=>("system" "typespec-alist")
(split-string "system::typespec-alist" ":" t)
=>("system" "" "typespec-alist")

グチャグチャになってしまった。
xyzzy/Emacsにはsplit-string関数があるけど、CLにはないから結構便利そう。

関数書いてから気づいたんだが、split-stringって正規表現使えるのね

(split-string "Soup is good food" "o*")
=>("S" "up is g" "d f" "d")

0 件のコメント:

コメントを投稿