lispとrubyとpythonと その2(common lisp)
common lispでの
・文字列
連結
分割
切り出し
比較
・同値性、同一性
・変換
数字→文字列
文字列→数字
文字列→時刻
時刻→文字列
・標準出力に文字列出力
・標準入力から読み込み
・コマンドライン引数の受け取り
が以下。
やっぱりというか標準ライブラリが貧弱。
いちいち探して入れるのはやっぱり面倒くさい。
;;文字列連結 ;;concatenateで連結 (setf s1 (concatenate 'string "abc" "あいうえお")) (print s1) ;;formatで連結する手もある (setf s2 (format nil "~A~A" "abc" "あいうえお")) (print s2) ;;文字列の分割 ;;標準ではsplit的なものがない。 ;;splitくらいつくりゃあいいんだけど、やっぱ作るの面倒くさい。 ;;この辺のいたらなさがlispの辛いところ。 ;;split-sequenceを入れて使うことにする ;;インストールはこんな感じで、asdfで入れる。 ;; ;; CL-USER> (require 'asdf) ;; ;; NIL ;; ;; CL-USER> (require 'asdf-install) ;; ;; ("ASDF-INSTALL") ;; ;; CL-USER> (asdf-install:install 'split-sequence) ;; ;; NIL (require 'split-sequence) (setf seq (split-sequence:split-sequence #\, "あaあ,いiい,うuう,えeえ")) (mapc #'(lambda (s) (format t "~A~%" s)) seq) ;;文字列の検索 ;;これも標準ではない?? ;;しょうがないからcl-ppcreで。 (require 'cl-ppcre) ;;ヒットすれば多値が戻る (multiple-value-bind (s e) (cl-ppcre:scan "かきくけこ" "あいうえおかきくけこさしすせそ") (format t "~A-~A~%" s e)) ;;部分文字列の取得 (format t (subseq "あいうえおabdde")) ;;特定の文字の場所を探して部分文字列取得とかありがちじゃない? (setf target "あいうえお-かきくけこ") (multiple-value-bind (s e) (cl-ppcre:scan "-" target) (if s (print (subseq target (1+ s))))) ;;文字列比較 ;;普通の比較 (if (string= "aaa" "aaa") (format t "true")) ;;case-insensitiveな比較 (if (string-equal "aaa" "AAA") (format t "true")) ;;common lisp の eq、eql、equal、equalpは分かりにくくて、使い辛いと思う。 ;;eq 同一性の比較 ただし同じ数値とかちゃんと比較できないこともある ;;ポインタの比較だけするから早い (setf a 'a) (setf b a) (if (eq a b) (format t "true")) ;;eql 同一性の比較 (if (eql 1 1) (format t "true")) ;;equal リストなら内容が一致(同値)であればtrueになる ;;文字列もこれ使う(もしくはstring=) ;;他にもなにやらルールがあるが覚えられん (if (equal '(a b c) '(a b c)) (format t "a")) ;;equalp equalよりもさらにルーズなルール ;;大文字、小文字の区別をしなかったり、1と1.0が等しかったり (if (equalp 1 1.0) (format t "a")) ;;数字→文字列 (setf ns (format nil "~A" 123.000)) (format t ns) ;;文字列→数字 (setf i (read-from-string "1234.000")) (format t "~A" (1+ i)) ;;文字列→数字その2 (setf i1 (parse-integer "123")) (format t "~A" (1+ i1)) ;;日付→文字列 ;;;現在日付 (setf dt (get-universal-time)) ;;;表示 (multiple-value-bind (s m h d mm y) (decode-universal-time dt) (format t "~A/~A/~A ~A:~A:~A" y mm d h m s)) ;;;sbcl限定であればこんなのもOK (sb-int:format-universal-time t dt) (multiple-value-bind (s m h d mm y) (decode-universal-time dt) (sb-int:format-decoded-time t s m h d mm y)) ;;文字→日付 ;;;これも標準ではない。。。 ;;;しょうがないからなにかないか探す。 ;;;net-telent-dateでなんとかなりそう。 ;;;が、asdfで入れようと思ったんだけど、ダウンロードがはじまらない。 ;;;webサーバが死んでるのか?? ;;;aptで入れれたりしないかな・・・とapt-cache search net-telent-dateとしてみた。 ;;;xxxi@alex:~$ apt-cache search net-telent-date ;;;cl-net-telent-date - Common Lisp utilities for printing and parsing dates ;;;これでいいのかな?? ;;;とりあえずこれにしてみた。 ;;;使い方は↓な感じ ;;;しかしなんでこれ「.」区切りなんだろ。。。普通に「-」でいいじゃん。。。 (require 'net-telent-date) (setf ymdhms (net.telent.date:parse-time "2008/07/04 12:37:06")) (sb-int:format-universal-time t ymdhms) ;;標準出力に出力 ;;;色々ある (print "hello world") (princ "こんにちは") ;;;formatの第一引数にtを渡すと出力さきは標準出力になる (format t "こんにちは") ;;標準入力から読み込み (do ((l (read-line *standard-input*) (read-line *standard-input*))) ((string-equal l "exit") 'EXIT) (format t "print:~A" l)) ;;コマンドライン引数の取得 ;;処理系依存らしい。sbclであれば*posix-argv*に入っている (dolist (arg *posix-argv*) (format t "args:~A~%" arg))