逆引きruby(文字列)をscheme(gauche)で2
コメントをもらったので、その情報を元に追加します。
全体的にsrfi-13の手続きを把握しきれていなかったみたいです。
そして#`"..."を不完全な文字列と勘違いしていました(本当は文字列補間の構文)
文字列中の式を評価し値を展開する(勘違い)
#~""は不完全な文字列
#`"..." は文字列補間の構文で不完全な文字列とは呼ばないそうです。勘違いしてました。(#*"..." が不完全な文字列)
不完全な文字列と通常の文字列ではstring-lengthの返す値が違います。
また、writeで出力した場合にも、出力結果が異なります。
現在のエンコーディングで解釈しようのない文字列を不完全な文字列というみたいです。
("Gauche - A Scheme Interpreter#不完全な文字列"より)
(string-incomplete? "あaaa") ; => #f (string-incomplete? #*"あaaa") ; => #t (write "あaaa") ; => "あaaa"#<undef> (write #*"あaaa") ; => #*"\xe3\x81\x82aaa"#<undef> (string-length "あaa") ; => 3 (string-length #*"あaa") ; => 5 (string-size "あaa") ; => 5 (string-size #*"あaa") ; => 5 (string-incomplete? (string-append "あ" "あ")) ; => #f (string-incomplete? (string-append "あ" #*"あ")) ; => #t (string-incomplete? (string-append #*"あ" "あ")) ; => #t
大文字と小文字の入れ替え
srfi-13のstring-mapを使うと文字列を文字のリストに変換する必要がないようです。
(use srfi-13) (define (swap-case str) (string-map (lambda (c) (cond ((char-upper-case? c) (char-downcase c)) ((char-lower-case? c) (char-upcase c)) (else c))) str)) (swap-case "I love Scheme") ; => "i LOVE sCHEME"
部分文字列を取り出す
string-copyを使うと終了位置を省略できるようです。
部分文字列を取り出すのは、O(n)ではなくほぼO(1)でできるそうです。
(逆に1文字変更するだけでも、元の文字列がコピーされるため、O(N)のコストがかかってしまうそうです。)
(define s "Apple Banana Orange") (substring s 0 5) ; => "Apple" (substring s 6 12) ; => "Banana" (substring s 13 -1) ; => "Orange" (string-copy s 0 5) ; => "Apple" (string-copy s 6) ; => "Banana Orange" (string-copy s 13) ; => "Orange"
部分文字列を置き換える
srfi-13のstring-replaceで部分文字列を置き換えられるようです。
(define s "Apple Banana Orange") (string-replace s "Vine" 0 5) ; => "Vine Banana Orange" (let ((s* (string-replace s "Vine" 0 5))) (string-replace s* "Lemmon" 5 11)) ; => "Vine Lemmon Orange"
文字列を1文字ずつ処理する
srfi-13のstring-{for-each,fold}を使えば、listに変換しなくても1文字ずつ処理できます。
(string-fold (lambda (c n) (+ (char->integer c) n)) 0 "Scheme") ; => 597
上記の例は、文字列の各文字の文字コードを合計を計算しています
文字列を1行ずつ処理する
文字列ポートに変換してからport-{for-each,fold}などを使う方法もあるそうです。
そういえば、文字列を出力ポートとして使うことはあっても、入力ポートとして使った経験はありませんでした。
(define s "this is test. scheme, the multi paradigm language") (with-input-from-string s (lambda () (port-fold (lambda (line i) (print i ": " line) (+ i 1)) 1 (lambda () (read-line))))) ;;>> 1: this is test. ;;>> 2: ;;>> 3: scheme, the multi paradigm language
文字列を暗号化する
次のバージョン(0.9.1)にはどのプラットフォームでも使えるbcryptのサポートが入ります。
(use util.bcrypt)とか(use gauche.bcrypt)で文字列を暗号化できるようになるかもしれません。
文字列中に含まれている任意文字列の位置を求める
srfi-13のstring-containsでできるそうです。
(string-contains s "Apple" 0) ; => 0 (string-contains s "Banana") ; => 6 (string-contains s "Apple" 6) ; => 13