srfi.13
- 文字列ライブラリ ¶文字列に関連する手続きの大きなセットを定義しています。
これは広く使われた初期のsrfiのひとつですが、いくつかの手続きは
その後のSchemeの発展と相性が良くないということがわかってきました。
srfi.152
- 文字列ライブラリ(簡略版)やsrfi.130
- カーソルを使う文字列ライブラリでは
このsrfiをより「現代的」なものにしようとしています。
新規に開発する場合はそれらのsrfiを見てみると良いでしょう。
このsrfiの多くの手続きは、文字列中の文字の位置を整数のインデックスで表します。 これはポータブルですが、マルチバイト文字列では効率が悪いです。 Gaucheは組み込みでより効率のよい文字列カーソルをサポートしており(文字列カーソル)、 SRFI-13の手続きは全て文字列インデックスを受け取るところに文字列カーソルも 渡せるようになっています。
• 一般規約: | ||
• 文字列についての述語: | ||
• 文字列の構築子: | ||
• 文字列の選択: | ||
• 文字列の色々な比較: | ||
• 文字列のプリフィックスとサフィックス: | ||
• 文字列の探索: | ||
• 文字列のケース(大文字小文字)マッピング: | ||
• 文字列の反転と追加: | ||
• 文字列のマッピング: | ||
• 文字列のローテーション: | ||
• 他の文字列操作: | ||
• 文字列のフィルタリング: | ||
• 低レベルな文字列に関する手続き: |
文字列ライブラリのAPIにはいくつか共通するものがありますが、 それぞれの関数の説明において繰り返しません。
以下の引数名はその型を暗に表しています。
これらの引数は文字列でなければなりません。
この引数は、文字、文字集合オブジェクト、あるいは1つの文字を引数に取り 真偽値を返す述語のいずれかです。“文字にchar/char-set/predを適用する” の意味はそれぞれ、char/char-set/predが文字ならば与えられた文字と比較される、 char/char-set/predが文字集合ならばその文字集合に与えられた文字が 含まれるかを検査する、char/char-set/predが述語ならばそれを与えられた 文字に適用する、となります。“ある文字がchar/char-set/predを満足する” とは、その文字への前述のような適用が真値を返すという意味になります。
SRFI-13の関数の多くは、その操作が実行される対象入力文字列の 範囲を限定する開始インデックスと終了インデックスをオプショナルな 引数として取ります。開始(start番目)の文字は含まれ、 終了(end番目)の文字は含まれません。 これらが指定されるとき、0 <= start <= end <= length of the stringが 満たされなければなりません。startとendのデフォルト値は、 それぞれ0と文字列の長さです。
shared
バージョンいくつかの関数は、その名前に“/shared”が付きます。 SRFI-13では、それらの関数はより良いパフォーマンスのために 入力文字列の一部を共有しても良いと定義しています。 Gaucheは、共有文字列という概念を持っていませんし、 それらの関数は単に共有でないバージョンの変名に過ぎません。 しかし、Gaucheは内部的には文字列の保存場所を共有しているので、 一般的には部分文字列をコピーするオーバヘッドについて心配する 必要はありません。
right
バージョンほとんどの関数は、入力文字列を左から右へと扱います。 いくつかの関数は、その名前に“-right”が付き、右から左へと 扱うものがあります。
[SRFI-13]{srfi.13
}
sが空文字列、""
なら、#t
を返します。
[SRFI-13]{srfi.13
}
sに含まれる全ての文字がchar/char-set/predを
満足するかを検査します。満足するならば、string-every
は
最後に適用されたchar/char-set/predが返した値を戻り値とします。
どの適用も#f
を返した場合は、string-every
はすぐに
#f
を返します。
[SRFI-13]{srfi.13
}
sに含まれるいずれかの文字がchar/char-set/pred
を満足するかを検査します。いずれかの文字が満足するならば、
string-any
はその適用が返した値を戻り値とします。
どの文字もchar/char-set/predを満たさなければ、#f
が返ります。
[SRFI-13]{srfi.13
}
procは整数を1つ引数として取り文字を返す手続きで
なければなりません。string-tabulate
は、そのi番目の
文字が(proc i)
で計算されるような文字列を返します。
(string-tabulate (lambda (i) (integer->char (+ i #x30))) 10) ⇒ "0123456789"
[SRFI-13]{srfi.13
}
基本的な文字列構築手続きです。
p、f、gは手続きで、現在のシード値を受けとります。
停止述語pはいつ繰り返しを止めるかを判断します。それが真の値を返したら、
文字列構築は終了し、それまでに生成された文字が集められて文字列として返されます。
fはシード値から文字を生成する手続きです。gはシード値から次のシード値を
生成します。seed引数はシード値の初期値を指定します。
(string-unfold (^n (= n 10)) (^n (integer->char (+ n 48))) (^n (+ n 1)) 0) ⇒ "0123456789"
省略可能引数baseは、与えられれば生成される文字列のプレフィクスとなります。 make-finalは手続きで、繰り返しが終了した後の最後のシード値を受け取り、 文字列のサフィックスを返します。
(string-unfold (^n (= n 10)) (^n (integer->char (+ n 48))) (^n (+ n 1)) 0 "foo" x->string) ⇒ "foo012345678910"
[SRFI-13]{srfi.13
}
もうひとつの基本的な文字列構築器です。引数の意味はstring-unfold
と
同じですが、fの返す文字が右から左へと並べられます。
また、章句可能なbase引数はサフィックスに、
make-finalが返す文字列はプレフィクスになります。
(string-unfold-right (^n (= n 10)) (^n (integer->char (+ n 48))) (^n (+ n 1)) 0 "foo" x->string) ⇒ "109876543210foo"
[SRFI-13]{srfi.13
}
≡ (list->string (reverse char-list))
.
[SRFI-13]{srfi.13
}
Gaucheでは、引数endがオプショナルであることを除いて、
substring
と同じです。
(substring/shared "abcde" 2) ⇒ "cde"
[SRFI-13]{srfi.13
}
文字列sを、文字列targetのtstart番目以降へコピーします。
target文字列は変更可能でなければなりません。
オプションの引数startとendは、sの範囲を制限します。
コピーされた文字列がtargetの終端を越えたらエラーが通知されます。
(define s (string-copy "abcde")) (string-copy! s 2 "ZZ") s ⇒ "abZZe"
targetとsに同じ文字列を渡しても構いません。コピー元とコピー先の 領域が重なっていても、コピーは常に正しく行われます。
Gaucheでは、文字列を変更不可なオブジェクトとして扱うことを強く推奨しています。
内部的に、文字列オブジェクトは変更不可な文字列の実体へのポインタとなっています。
文字列を変更すると、新たな文字列実体がアロケートされそれが変更されるので、
破壊的手続きを使えばメモリアロケーションが節約できるということはありません。
どうしても文字列そのものを破壊的変更したい場合でない限りは、
非破壊版のstring-copy
を使いましょう。文字列を扱うその他の手続き参照。
[SRFI-13]{srfi.13
}
string-take
は、sの最初のnchars文字からなる文字列を返します。
string-drop
は、sから最初のnchars文字からなる文字列を
除いた残りを返します。*-right
バージョンは、文字列の最後から数えます。
返される文字列はいつもsのコピーであり、どの文字も削除されないことが
保証されています。
(string-take "abcde" 2) ⇒ "ab" (string-drop "abcde" 2) ⇒ "cde" (string-take-right "abcde" 2) ⇒ "de" (string-drop-right "abcde" 2) ⇒ "abc"
[SRFI-13]{srfi.13
}
文字列sがlenより短い場合は、charがそれぞれ左か
右にパディングされた長さlenの文字列を返します。
sがlenよりも長い場合は、len文字が右端か左端から
取り除かれます。Charのデフォルト値は#\space
です。
startとendが与えられると、sの部分文字列がソース
文字列として使われます。
(string-pad "abc" 10) ⇒ " abc" (string-pad "abcdefg" 3) ⇒ "efg" (string-pad-right "abc" 10) ⇒ "abc " (string-pad "abcdefg" 10 #\+ 2 5) ⇒ "+++++++cde"
[SRFI-13]{srfi.13
}
sからchar/char-set/predにマッチする文字を削除します。
String-trim
はsの左から文字を削除し、
string-trim-right
は右から、string-trim-both
は
両端から削除します。
Char/char-set/predのデフォルト値は#[\s]
、つまり空白文字の
文字集合です。startとendが与えられると、sの部分文字列が
ソース文字列として使われます。
(string-trim " abc ") ⇒ "abc " (string-trim-right " abc ") ⇒ " abc" (string-trim-both " abc ") ⇒ "abc"
[SRFI-13]{srfi.13
}
文字列s1とs2をコードポイント毎に左から比較します。
不一致がs1のインデックスkで見つかった場合、対応するs2の
コードポイントよりs1のコードポイントの方が小さければ
proc<をkを引数にして呼び出し、逆に大きければ
proc>をkを引数にして呼び出します。
二つの文字列が等しければ、proc=が、s1の比較された最後のインデックスを
引数にして呼び出されます。
(string-compare "abcd" "abzd" (^i `(< ,i)) (^i `(= ,i)) (^i `(> ,i))) ⇒ (< 2) (string-compare "abcd" "abcd" (^i `(< ,i)) (^i `(= ,i)) (^i `(> ,i))) ⇒ (= 3)
省略可能引数は入力の文字列の比較すべき範囲を制限します。 但し、proc<、proc=、proc>に渡されるインデックスは 常にs1の最初から数えたものになります。
(string-compare "zzabcdyy" "abcz" (^i `(< ,i)) (^i `(= ,i)) (^i `(> ,i)) 2 6 0 4) ⇒ (< 5) (string-compare "zzabcdyy" "abcz" (^i `(< ,i)) (^i `(= ,i)) (^i `(> ,i)) 2 5 0 3) ⇒ (= 4)
string-compare-ci
は大文字小文字を区別しない比較です。
文字毎の大文字小文字変換を行って比較するので、文字列の長さが変わる
大文字小文字変換のケース (ドイツ語のエスツェット等) は考慮されません。
[SRFI-13]{srfi.13
}
二つの文字列s1とs2を比較します。省略可能引数で
それぞれの文字列の一部のみを比較するように指定できます。
比較は文字ごとに行われます。
註: 組み込み手続きのstring=?
等も文字毎の比較に使えますが、
引数の取り方が違います。文字列の色々な比較参照。
[SRFI-13]{srfi.13
}
二つの文字列s1とs2を、大文字小文字を区別せずに比較します。
省略可能引数でそれぞれの文字列の一部のみを比較するように指定できます。
大文字小文字の畳み込みと比較は文字ごとに行われます。複数の文字に
影響を与えるような大文字小文字の畳み込みは考慮しません。
註: Gaucheには他に2種類の大文字小文字を区別しない文字列比較手続き群があります。
どちらもstring-ci=?
等のようにクエスチョンマーク付きの名前を持っています。
Gauche組み込みのものは文字毎に大文字小文字を畳み込みます
(文字列の色々な比較参照)。一方、gauche.unicode
にあるものは
文字列としての畳み込みを行います(フルセットの大文字小文字変換参照)。
R7RS版は後者です。
[SRFI-13]{srfi.13
}
(註: Gaucheは、SRFI-128に準拠したstring-hash
とstring-ci-hash
を
組み込みで持っています。詳しくはハッシュ参照。
SRFI-13のAPIはSRFI-128の上位互換になっています。内部で使っているハッシュ
アルゴリズムは一緒なので、省略可能引数を全て省略したSRFI-13のstring-hash
は、
組み込みのstring-hash
と同じ値を返します。
一方、組み込みのstring-ci-hash
は文字列として大文字小文字の畳み込みを
行います(ドイツ語のエスツェットとSS
は等しく扱われます)が、SRFI-13の
string-hash-ci
は文字毎に大文字小文字を畳み込むように定められているので、
結果が異なる可能性があります。特に強い理由がなければ、新しいコードは
組み込みのSRFI-128版を使うことをおすすめします。)
文字列sのハッシュ値を計算して返します。string-hash-ci
では
ハッシュ値を計算する前に各文字について大文字小文字を畳み込みを行います。
省略可能引数boundは、与えられたなら正の正確な整数でなければならず、
返される値は0から(- bound 1)
までの値に制限されます。
startとendは、与えられればs中の対象となる部分文字列を
指定します。
[SRFI-13]{srfi.13
}
二つの文字列s1とs2の、共通するプレフィクスもしくはサフィックスの
長さを返します。省略可能引数はそれぞれの文字列の探索範囲を限定します。
*-ci
版は文字ごとに、大文字小文字を区別しない比較を行います。
(string-prefix-length "abacus" "abalone") ⇒ 3 (string-prefix-length "machine" "umbrella") ⇒ 0 (string-suffix-length "peeking" "poking") ⇒ 4 (string-prefix-length "obvious" "oblivious" 2 7 4 9) ⇒ 5
[SRFI-13]{srfi.13
}
それぞれ、s1がs2のプレフィクスまたはサフィックスになっていた場合に
#t
を、それ以外の場合に#f
を返します。
省略可能引数はそれぞれの文字列の探索範囲を限定します。
*-ci
版は文字ごとに、大文字小文字を区別しない比較を行います。
(string-prefix? "sch" "scheme") ⇒ #t (string-prefix? "lisp" "scheme") ⇒ #f (string-suffix? "eme" "scheme") ⇒ #t (string-suffix? "eme" "lisp") ⇒ #f (string-prefix? "mit-scheme" "scheme-family" 4) ⇒ #t
[SRFI-13]{srfi.13
}
文字列sの中で、char/char-set/predにマッチする
最初の要素を探し、そのインデックスを返します。
sの中にchar/char-set/predが見つからない場合は、#f
を
返します。オプションのstartとendは、sの中で検索対象と
なる範囲を制限します。
(string-index "Aloha oe" #\a) ⇒ 4 (string-index "Aloha oe" #[Aa]) ⇒ 0 (string-index "Aloha oe" #[\s]) ⇒ 5 (string-index "Aloha oe" char-lower-case?) ⇒ 1 (string-index "Aloha oe" #\o 3) ⇒ 6
ポータビリティよりも速度を重視する場合は、Gaucheのビルトイン手続き
string-scan
(文字列を扱うその他の手続き)を参照して下さい。
[SRFI-13]{srfi.13
}
char/char-set/predにマッチしない最初の要素を探し、
そのインデックスを返します。そのような要素が見つからない場合、#f
を
返します。オプションのstartとendは、sの中で検索対象と
なる範囲を制限します。
[SRFI-13]{srfi.13
}
sの中で、char/char-set/predにマッチする要素の数を
カウントします。オプションのstartとendは、sの中で検索対象と
なる範囲を制限します。
[SRFI-13]{srfi.13
}
s1の中で、文字列s2を探します。見つかった場合は、
s1でマッチした文字列が始まるインデックスを返します。そうでなければ、
#f
を返します。
オプションのstart1、end1、start2、end2は、
s1とs2の範囲を制限します。
ポータビリティよりも速度を重視する場合は、Gaucheのビルトイン手続き
string-scan
(文字列を扱うその他の手続き)を参照して下さい。
[SRFI-13]{srfi.13
}
文字列sをタイトルケース、大文字、小文字にそれぞれ変換します。
これらの手続きは、文字ごとにchar-upcase
等を使った変換を行います。
すなわち、string-upcase
とstring-downcase
は以下の操作と
考えることができます。
(string-upcase s) ≡ (string-map char-upcase s) (string-downcase s) ≡ (string-map char-downcase s)
一文字がケース変換によって複数文字になるような場合も考慮したい場合は、
gauche.unicode
モジュールに定義されている同名の手続きを使ってください
(フルセットの大文字小文字変換参照)。
string-titlecase!
、string-upcase!
、
string-downcase!
はその場で更新するバージョンで、sを破壊的に
変更します。ただし、Gaucheでは文字列の変更は新たな文字列を作るのと効率的に
何ら変わりがありません。これらの手続きは互換性のためだけに用意されています。
[SRFI-13]{srfi.13
}
sの文字の位置を逆順にした文字列を返します。
string-reverse!
はsそのものを変更します。
(string-reverse "mahalo") ⇒ "olaham" (string-reverse "mahalo" 3) ⇒ "ola" (string-reverse "mahalo" 1 4) ⇒ "aha" (let ((s (string-copy "mahalo"))) (string-reverse! s 1 5) s) ⇒ "mlahao"
[SRFI-13]{srfi.13
}
文字列のリストを連結します。
(string-concatenate '("humuhumu" "nukunuku" "apua" "`a")) ⇒ "humuhumunukunukuapua`a"
[SRFI-13]{srfi.13
}
string-concatenate
とstring-append
の“共有”
バージョンです。Gaucheでは、これらは単に別名です。
[SRFI-13]{srfi.13
}
string-listを連結する前に逆順にします。
Gaucheでは、“共有”バージョンは全く同じ動作をします。
[SRFI-13]{srfi.13
}
string-map!
は、sの全ての文字に対してprocを
適用し、その結果をsに格納します。
procは文字を返さねばなりません。
(let ((s (string-copy "wikiwiki"))) (string-map! char-upcase s 4) s) ⇒ "wikiWIKI"
[SRFI-13]{srfi.13
}
文字列に対して動作するfoldやfold-right (リストをたどる手続き参照)
です。
(string-fold cons '() "abcde") ⇒ (#\e #\d #\c #\b #\a) (string-fold-right cons '() "abcde") ⇒ (#\a #\b #\c #\d #\e)
[SRFI-13]{srfi.13
}
procをsの各文字について、左から右の順に呼びます。procの結果は
捨てられます。
省略可能なstartとend引数は整数の文字インデックスか
文字列カーソルで、対象となる文字列の範囲を制限します。
[SRFI-13]{srfi.13
}
sが左右に無限に繰り替えされているとみなし、その整数インデックス
のfromからtoまでを切り出して返します。
toが省略された場合はsの長さが使われます。
例えば、sがabcde
の場合、まずそれを無限の
文字列...abcdeabcdeabcde...
とみなします。
つまり整数nに対して5n番目の文字は常に#\a
です。
これはnが負の領域にも拡張されます。
(xsubstring "abcde" 2 10) ⇒ "cdeabcde" (xsubstring "abcde" -9 -2) ⇒ "bcdeabc"
省略可能なstartとend引数は整数の文字インデックスか
文字列カーソルで、与えられた場合、
(xsubstring (substring s start end) from to)
と同じ動作となります。
[SRFI-13]{srfi.13
}
(string-copy! target tstart (xsubstring s sfrom sto start end))
と同じ動作をします。
[SRFI-13]{srfi.13
}
文字列s1のstart1文字目(inclusive)からend1文字目(exclusive)
までを文字列s2に置き換えた文字列を新たに作って返します。s1, s2は
変更されません。
オプショナルな引数start2、end2が与えられた場合は、
s2がまずそれらによって切り取られて置換文字列として使われます。
置き換える隙間の大きさ、つまり(- end1 start1)
は
s2と同じ長さである必要はありません。
実質的に、この手続きは次のコードと等価です。
(string-append (substring s1 0 start1) (substring s2 start2 end2) (substring s1 end1 (string-length s1)))
[SRFI-13]{srfi.13
}
文字列 s を、token-set で指定される文字集合で
構成される、空でない最大限連続した文字のシーケンスのそれぞれを
要素とするリストを返します。
token-set のデフォルト値は char-set:graphic
(定義済み文字集合参照)。
同様の機能を提供する、しかし異なる基準を持つ、Gauche の組み込み手続き
string-split
(文字列を扱うその他の手続き 参照) も見て下さい。
[SRFI-13]{srfi.13
}
それぞれ、文字列s中の文字のうちchar/char-set/predで示される
テストを通る、または通らない文字からなる文字列を返します。
(string-filter char-upper-case? "Hello, World!") ⇒ "HW" (string-delete char-upper-case? "Hello, World!") ⇒ "ello, orld!" (string-delete #\l "Hello, World!") ⇒ "Heo, Word!" (string-filter #[\w] "Hello, World!") ⇒ "HelloWorld"
註: SRFI-13は制定後に改訂され、引数char/char-set/predとsの
順序が逆になりました。制定時点では引数順は
(string-filter s pred)
で、Gaucheもそれに従って実装していました。
しかし既存の実装のほとんどは(string-filter pred s)
という順序に
なっています。SRFI-13の参照実装がそうだったからです。
0.9.4からGaucheも現在のSRFI-13の実装に合わせましたが、 以前の仕様で書かれたコードとの互換性を保つため、 引数順を逆にしても動作するようになっています。 新しく書かれるコードは、現在のSRFI-13の引数順を使うのが良いでしょう。
SRFI-13に似せた他の文字列処理ユーティリティを書くのに便利なヘルパー関数です。
[SRFI-13]{srfi.13
}
多くのSRFI-13の手続きは、省略可能引数としてstartとend引数を取ります。
この手続きは、残余引数リストargsにstartとendが指定されているかを調べ、
指定されていればそれらを、されていなければ適切なデフォルト値を返します。
procはエラー通知に使われる手続きの名前 (シンボル)、 sは処理すべき文字列です。
どちらの手続きも、argsの最初にstart引数があり、その次にend引数が
あることを期待します。end引数が省略されていた場合はsの長さが、
start引数も省略されていた場合は0
が使われます。
引数が与えられた場合は、それらは正確な整数で
0
<= start <= end
<= (string-length s)
を満たしていなければなりません。そうでなければエラーが投げられます。
argsに二つ以上の引数が含まれていた場合、
string-parse-final-start+end
はエラーを通知します
(つまり、最長でも引数リストがend引数で終わる場合に使えます)。
一方、string-parse-start+end
は、余分な引数を許し、それを
start/endの値とともに返します。
どちらの関数も3つの値を返します。余分な引数のリスト、startの値、endの値です。
[SRFI-13]{srfi.13
}
[SRFI-13]{srfi.13
}
[SRFI-13]{srfi.13
}
[SRFI-13]{srfi.13
}
[SRFI-13]{srfi.13
}