lispとrubyとpythonと その2(common lisp) ver2
ちまちまと更新。
common lispは日付まわりが面倒くさいなぁ。
universal-timeが基本になってるのがすでに微妙。
整備されたライブラリが欲しい・・・。
;;文字列連結 ;;concatenateで連結 (format t (concatenate 'string "あいう" "えお")) ;;->あいうえお ;;formatで連結 (print (format nil "~A~A" "あいう" "えお")) ;;->"あいうえお" ;;どちらもめんどい ;;文字列の分割 ;;split-sequenceはやめ ;;cl-utilitiesで ;;マニュアルはここ ;;http://common-lisp.net/project/cl-utilities/doc/ ;;asdfで入れとくこと (require 'cl-utilities) (setf sq0 (cl-utilities:split-sequence #\, "あああ,いいい,ううう,えええ,おおお")) (mapc #'(lambda (s) (format t "~A~%" s )) sq0) ;; ->あああ ;; いいい ;; ううう ;; えええ ;; おおお (setf sq1 (cl-utilities:split-sequence-if #'(lambda (c) (or (char= c #\,) (char= c #\.))) "あああ,いいい.ううう,えええ.おおお")) (mapc #'(lambda (s) (format t "~A~%" s)) sq1) ;;->あああ ;; いいい ;; ううう ;; えええ ;; おおお ;;文字列検索 ;;cl-ppcreを使う (require 'cl-interpol) (cl-interpol:enable-interpol-syntax) (require 'cl-ppcre) (if (cl-ppcre:scan #?/かきくけこ/ #?"あいうえおかきくけこさしすせそ") (format t "みつかった~%") (format t "みつからない~%")) ;;->みつかった (if (cl-ppcre:scan #?/たちつてと/ #?"あいうえおかきくけこさしすせそ") (format t "みつかった~%") (format t "みつからない~%")) ;;->みつからない ;;みつかったら開始位置と終了位置が多値で返る (multiple-value-bind(s e) (cl-ppcre:scan #?/かきくけこ/ #?"あいうえおかきくけこさしすせそ") (format t "~A ~A~%" s e)) ;;->5 10 ;;部分文字列の取得 (format t (subseq "あいうえおかきくけこさしすせそ" 5 10)) ;;->かきくけこ ;;特定の文字の場所を探して部分文字列取得とかありがちじゃない? (setf target "あいうえお-かきくけこ") (multiple-value-bind(s e) (cl-ppcre:scan #?/-/ target) (if s (format t "~A~%" (subseq target 0 s)))) ;;->あいうえお ;;文字列比較 ;;普通の比較 (if (string= "aaa" "aaa") (format t "true~%")) ;;->true ;;case-insensitiveな比較 (if (string-equal "aaa" "AAA") (format t "true~%")) ;;->true ;;同値性と同一性 ;;比較にはeq、eql、equal、equalpがある ;;eqはポインタの比較 (setf val1 '(a b c)) (setf val2 '(a b c)) (setf alias val1) (if (eq val1 alias) (format t "true~%") (format t "false~%")) ;;->true (if (eq val1 val2) (format t "true~%") (format t "false~%")) ;;->false ;;eql ;;数値、文字比較。型が一致してeqか同じ値なら真 (if (eql 1 1) (format t "true~%") (format t "false~%")) ;;->true (if (eql 1 1.0) (format t "true~%") (format t "false~%")) ;;->false ;;equal ;;数値、文字列でeqlか型が一致して同じ値なら真 (setf val1 "hello") (setf val2 "hello") (if (equal val1 val2) (format t "true~%") (format t "false~%")) ;;->true (if (equal 1 1.0) (format t "true~%") (format t "false~%")) ;;->false ;;equalp ;;数値なら型が違ってもいい ;;文字列なら大文字小文字を気にしない (if (equalp 1 1.0) (format t "true~%") (format t "false~%")) ;;->true (if (equalp "aaa" "AAA") (format t "true~%") (format t "false~%")) ;;->true ;;数値->文字列変換 (setf ns (format nil "~A" 123.000)) (format t ns) ;;->123.0 (setf ns1 (write-to-string 123.000)) (format t ns1) ;;->123.0 ;;文字列->数値変換 (setf sn (parse-integer "123")) (format t "~A~%" sn) ;;->123 (setf sn1 (read-from-string "123.000")) (format t "~A~%" sn1) ;;->123.0 ;;日付->文字列変換 ;;現在日付取得 ;;universal-timeは1900年から経過した秒数 (setf dt (get-universal-time)) (multiple-value-bind (s m h dd mm yy) (decode-universal-time dt) (format t "~A/~A/~A ~A:~A:~A" yy mm dd h m s)) ;;->2008/12/14 1:43:6 ;;metatilitiesを使ってもオケ ;;asdfでインストールできる ;;でもrequireしたらなーんかコンパイルしてるときに/usr/lib/sbcl/site/...のpermissionエラーになる ;;めんどうだからchmodしちゃった・・・ ;;metatilitiesのリファレンスはここ ;;http://common-lisp.net/project/metatilities/documentation/metabang.utilities-package/index.html ;;metatilitiesでuniversal-timeを文字に変えるのはformat-date ;;フォーマットの指定の仕方はここ ;;http://common-lisp.net/project/metatilities/documentation/metabang.utilities-package/function-format--date.html (require 'metatilities) (metatilities:format-date "%Y/%m/%d %H:%M:%S" (get-universal-time)) ;;->"2008/12/13 23:22:15" ;;ミリ秒単位での取得 ;;universal-timeが秒数なのでclの範囲ではとれない ;;システム固有の機能を使う ;;sbcl限定 ;;参考っていうかそのまま ;;http://ja.doukaku.org/184/lang/commonlisp/ (defun get-decode-universal-time-with-millisecond() (multiple-value-bind (time ms) (sb-unix::system-real-time-values) (multiple-value-bind (s mm h d m y) (decode-universal-time (+ (encode-universal-time 0 0 0 1 1 1970 0) time)) (values ms s mm h d m y)))) (multiple-value-bind (ms s mm h d m y) (get-decode-universal-time-with-millisecond) (format t "~A/~A/~A ~A:~A:~A.~A~%" y m d h mm s ms)) ;;->2008/12/13 14:22:28.503 ;;文字列をuniversal-timeにする ;;metatilities:parse-date-and-time-stringだとMM/dd/yyyy HH:mm:ssしかparseできない ;;日本には馴染まないからダメ ;;universal-time->文字列->universal-time->文字列 (metatilities:format-date "%Y/%m/%d %H:%M:%S" (metatilities:parse-date-and-time-string (metatilities:format-date "%m/%d/%Y %H:%M:%S" (get-universal-time)) t)) ;;->"2008/12/14 01:23:40" ;;net.telent.date:parse-timeならyyyy/MM/dd HH:mm:ssをuniversal-timeにできる ;;universal-time->文字列->universal-time->文字列 (require 'net-telent-date) (metatilities:format-date "%Y/%m/%d %H:%M:%S" (net.telent.date:parse-time (metatilities:format-date "%Y/%m/%d %H:%M:%S" (get-universal-time)))) ;;->"2008/12/14 01:27:24" ;;日付、時刻計算 ;;universal-timeは1900/1/1 00:00:00からの秒数を持ってるだけだから普通に足し算引き算すればいい (let ((date1 "2008/12/13 00:00:00") (date2 "2008/12/24 00:00:00")) (format t "あと~A時間でクリスマスイブ~%" (/ (/ (- (net.telent.date:parse-time date2) (net.telent.date:parse-time date1)) 60) 60))) ;;->あと264時間でクリスマスイブ ;;標準出力に出力 ;;;色々ある (print "hello world") ;;->"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))