For Gauche 0.9.10


Next: , Previous: , Up: ライブラリモジュール - Gauche拡張モジュール   [Contents][Index]

9.35 gauche.unicode - Unicodeユーティリティ

Module: gauche.unicode

このモジュールは、Unicodeのコードポイントの列に対する様々な操作を提供します。

Gaucheはコンパイル時に、内部文字エンコーディングとしてUnicode以外も選べます。 その場合、文字列に対して完全にUnicode互換の動作を提供できない場合があります。 そこで、本モジュールの多くの操作は、文字列を対象にするものと、 コードポイントの数値のシーケンスを対象にするものの両方で提供されます。

Gaucheの内部エンコーディングがnoneeuc-jpsjisの場合は、 文字および文字列に対する操作はUnicode標準で定義されたものと完全には一致しないでしょう。 操作の結果が、内部エンコーディングでは定義されていない文字になった場合、 それは代替文字に置き換えられます。各関数のエントリで詳しく説明してあります。

コードポイントの列に対する操作はGaucheの内部文字エンコーディングとは 無関係であり、Unicode標準の定義が完全にサポートされます。 Gaucheがutf-8でコンパイルされている場合、コードポイント列に 対する操作は、文字列に対する操作と (各要素をchar->integerおよび integer->charで変換すること以外は)一致します。 コードポイント列に対する操作はGaucheの内部文字エンコーディングにかかわらず ポータブルなアルゴリズムを必要とする場合に便利です。


Next: , Previous: , Up: Unicodeユーティリティ   [Contents][Index]

9.35.1 Unicode transfer encodings

このグループの手続きは、整数で表現されたコードポイントを扱います。 以下の説明で「オクテット」は0から255までの整数です。

これらの手続きは省略可能なstrictness引数を取ります。 この引数は、定義域外の入力が来たときの振る舞いを指定します。 指定できる値は次のいずれかです。

strict

定義域外の入力が来たらエラーを投げます。これがデフォルトの振る舞いです。

permissive

可能な限り、入力を有効な値であるかのように扱います。 例えば#x10ffffを越えるコードポイント値はUnicode標準では不正な値ですが、 utf-8の規則を拡張することでエンコード可能であり、文字列以外のバイナリデータを単にutf-8風に エンコードしたいだけの場合などには便利かもしれません。

replace

不正な入力を見たら、それをユニコード置換文字U+FFFDに置き換え処理を続行します。

ignore

可能であれば、不正な入力は無視します。

strictnesspermissivereplaceignoreであっても、 入力データの妥当な解釈ができない場合はエラーが投げられる可能性があります。

Function: ucs4->utf8 codepoint :optional strictness

{gauche.unicode} 整数のコードポイント値を受け取り、utf-8でエンコードされたオクテットのリストを返します。

(ucs4->utf8 #x3bb)  ⇒ (206 187)
(ucs4->utf8 #x3042) ⇒ (227 129 130)

strictnessstrictの場合(デフォルト)、 入力が#xd800#xdfffの間か、#x110000以上の場合は エラーを投げます。 strictnessreplaceであれば、そのような入力に対しては utf8シーケンス#xef, #xbf, #xbd (U+FFFD) がせ生成されます。 strictnesspermissiveの場合は、 0から#x7fffffffまでの入力が許されます。 入力が大きい場合はエンコードされた出力は5〜6オクテットになるでしょう (初期のutf-8の定義通り)。 strictnessignoreの場合は、 Unicodeとして不正なコードポイントに対しては空リストが返されます。

Function: utf8-length octet :optional strictness

{gauche.unicode} octetをutf-8シーケンスの最初のオクテットとみなし、 そこからひとつのコードポイントをデコードするのに全部で何オクテット必要かを返します。

octet引数が0から255の間の正確な整数でなければ、 strictness引数の値にかかわらず、エラーが投げられます。

strictnessstrictの場合(デフォルト)、 戻り値は1,2,3,4のいずれかです。octetがutf-8でエンコードされた Unicodeコードポイントの最初のオクテットとしてありえない値であれば エラーが投げられます。

strictnesspermissivereplaceの場合、 この手続きは0から6までの整数を返します。 入力が#xf8から#xfdの間の値(両端含む)の場合は 元々のutf-8仕様に基づいて5か6を返します (これらのオクテットはコードポイントが#x110000から #x7fffffffになるような値に相当します)。 引数が#x80から#xbfまでの値、および#xfe#xffの場合は、 utf-8の先頭バイトになり得ませんが、アプリケーションがこの不正なバイトだけを 適切に処理することを前提にして、1が返されます。

strictnessignoreの場合、この手続きは strictでエラーが投げられる入力値について0を返します。 それ以外はstrictの動作と同じです。

Function: utf8->ucs4 octet-list :optional strictness

{gauche.unicode} オクテットのリストを取り、それをutf-8のシーケンスとして解釈して、 デコードされたコードポイント及び残りのリストの2つの値を返します。

もし処理中に、0から255の間の正確な整数以外の値が入力に見つかったら、 strictnessの設定に関わらずエラーが投げられます。

それ以外の不正なutf-8シーケンスは、strictnessstrictであれば エラーに、ignoreであればスキップされます。 strictnessreplaceの場合は、そういったutf8シーケンスは U+FFFDを生成します。 strictnesspermissiveの場合は、 最初のutf-8仕様で許されていた全てのコードポイント、すなわち サロゲートペア領域(#xd800から#dfffまで)及び #x110000以上#x7fffffff以下のコードポイントも認識されます。 それ以外の不正なコードポイントはpermissiveであってもエラーになります。

Function: utf8->string u8vector :optional start end

[R7RS base] {gauche.unicode} u8vectorの、インデックスstart(含む)からend(含まない)までに 格納された値をutf-8オクテット列と見なし、文字列に変換して返します。 startendが省略された場合はそれぞれベクタの最初と最後が指定されたものと 解釈します。

Gaucheのネイティブエンコーディングがutf8の場合、 この手続きはまずu8vector->stringを試します (ユニフォームベクタの変換参照)。 もし入力がutf8シーケンスとして有効であれば、それが最も速いです。 しかし、入力に無効なutf8シーケンスが含まれていた場合、 この手続きは1文字づつ文字列を構築するモードにフォールバックし、 無効なutf8シーケンスの部分はUnicode置換文字U+FFFDに置き換えられます。 従って戻り値は常に完全な文字列です。 入力に不正なuft8シーケンスが含まれていたかどうかを知りたい場合は u8vector->stringを直接呼んでください。

Gaucheのネイティブエンコーディングがutf8以外の場合、 U+FFFDに相当するコードがないので、無効なutf8シーケンスに出会うと エラーが投げられます。

Function: string->utf8 string :optional start end

[R7RS base] {gauche.unicode} 文字列をutf8オクテットの並びにエンコードしてu8vectorとして返します。 省略可能なstartend引数は対象とする文字列の範囲を指定します。

Gaucheのネイティブエンコーディングがutf8であれば、この手続きは 単にstring->u8vectorを呼び出すだけです。 (ユニフォームベクタの変換参照)。 そうでなければまず入力文字列がutf8に変換されてから string->u8vectorが呼ばれます。

Function: ucs4->utf16 codepoint :optional strictness

{gauche.unicode} 整数で与えられたコードポイントをutf-16にエンコードして整数のリストとして返します。

strictnessstrictの場合(デフォルト)、 入力値は0から#xd7ffまでの間か、 #xe000から#x10ffffまでの間でなければなりません。 それ以外の場合はエラーが投げられます。 開いている部分はサロゲートに予約されているコードで、 この領域をutf-16にエンコードする方法は定義されていません。

strictnessreplaceであれば、そのような入力は #xfffd(Unicode置換文字)に置き換えられます。

strictnesspermissiveの場合、サロゲート領域の入力は エラーにならず、その値を唯一の要素とするリストが返されます。 負の値および#x110000の値についてはやはりエラーになります。

strictnessignoreの場合は、不正なコードポイント(サロゲート領域含む) については空リストが返されます。

註: permissiveモードでは#x10ffffより大きな値をutf-8にはエンコードできますが、 utf-16にはエンコードできません。

Function: utf16-length code :optional strictness

{gauche.unicode} codeは0から65535までの正確な整数でなければなりません。 codeがBMPのコードポイントなら1を、utf-16の上位サロゲートであれば2を返します。

strictnessstrictの場合(デフォルト)、codeが 下位サロゲートであったり、定義外の値であればエラーが投げられます。 strictnesspermissivereplaceの場合は、 やはり定義外の値であればエラーが投げられますが、 下位サロゲートの場合には1が返されます。 strictnessignoreの場合、 定義域外および下位サロゲートに対しては0が返されます。

Function: utf16->ucs4 code-list :optional strictness

{gauche.unicode} 正確な整数のリストを取り、それをutf-16の並びとして解釈します。 デコードされたucs4コードポイントおよび、残りのリストの二つの値を返します。

strictnessstrictの場合(デフォルト)、不正なutf-16の並びや 定義域外の値に出会ったらエラーが投げられます。 strictnesspermissiveの場合は、 やはり定義外の値であればエラーが投げられますが、 片方だけのサロゲートの場合にはそれがそのまま(コードポイントとして)返されます。 strictnessreplaceの場合は、 片方だけのサロゲートはU+FFFDに置換されます。 strictnessignoreの場合、 定義域外および片方だけのサロゲートは無視されます。

Function: utf16->string u8vector :optional endian ignore-bom? start end
Function: utf32->string u8vector :optional endian ignore-bom? start end

{guache.unicode} [R7RS scheme.bytevector] u8vectorに格納されたutf16およびutf32シーケンスを文字列に変換します。 utf16->stringは、 もし入力に不正なutf16シーケンス (ペアになっていないサロゲート) があった場合は、 それがUnicode置換文字(U+FFFD)に置き換えます。 入力のオクテット数がエンコーディング単位(utf16なら2オクテット、utf32なら4オクテット) の倍数でない場合はエラーが投げられます。

省略可能なendianignore-bom?引数は入力がUTF16BE/UTF32BEか UTF16LE/UTF32LEかを 決めます。ignore-bom?#fまたは省略された場合、まず入力の 最初の2オクテットが調べられ、BOMであればendianの値にかかわらず それがバイトオーダーを決定します。 入力がBOMで始まっていないか、ignore-bom?が真の値であれば、 endian引数がバイトオーダーを決定します。それが big-endianbigであればUTF16BE/UTF32BE、 little-endianlittlearm-little-endianであれば UTF16LE/UTF32LEとなります (エンディアンについてはエンディアンネス参照)。

ignore-bom?が与えられて真の値であった場合、 入力の先頭のBOMはコードポイントとみなされます。 endian#fまたは省略された場合は、 UTF16BE/UTF32BEとみなされます (これはR7RS scheme.bytevectorで定義された仕様です)。

なおR7RS scheme.bytevectorではignore-bom?引数は endianness-mandatoryと呼ばれています。動作は同じです。

省略可能なstartend引数は処理に先立って入力のオクテットシーケンスの 範囲を制限します(BOM検出も範囲制限後に行われます)。 この2つの引数はGauche独自拡張で、R7RS scheme.bytevectorでは定義されていません。

Function: string->utf16 str :optional endian add-bom? start end
Function: string->utf32 str :optional endian add-bom? start end

{gauche.unicode} [R7RS scheme.bytevector] 文字列strをutf-16またはutf-32にエンコードしたオクテット列をu8vectorで返します。

省略可能なendian引数は、エンコーディングがUTF16BE/UTF32BEかUTF16LE/UTF32LEかを決めます。 シンボルbig-endianbigが渡されたらUTF16BE/UTF32BE、 シンボルlittle-endianlittlearm-little-endianが 渡されたらUTF16LE/UTF32LEになります。省略されるか#fならUTF16BE/UTF32BEになります。 バイトオーダーについての詳細はエンディアンネスを参照してください。

二つめの省略可能引数add-bom?にもし真の値が与えられたら、 出力の先頭にBOMが含められます。省略されるか#fであればBOMは付加されません。

続く省略可能引数startendは入力文字列strの特定の範囲だけを 対象とするのに使います。

R7RSのscheme.bytevectorではendian引数だけを認めています。 残りはGaucheの拡張です。


Next: , Previous: , Up: Unicodeユーティリティ   [Contents][Index]

9.35.2 Unicode text segmentation

These procedures implements grapheme-cluster and word breaking algorithms defined in UAX #29: Unicode Text Segmentation.

Function: string->words string
Function: codepoints->words sequence

{gauche.unicode} 与えられた文字列あるいはコードポイントシーケンス(コードポイントを要素とする <sequence>オブジェクト)から、単語のリストを返します。 各単語はそれぞれ、文字列あるいはコードポイントシーケンスで表現されます。

(string->words "That's it.")
 ⇒ ("That's" " " "it" ".")
(codepoints->words '(84 104 97 116 39 115 32 105 116 46)
 ⇒ ((84 104 97 116 39 115) (32) (105 116) (46))
(codepoints->words '#(84 104 97 116 39 115 32 105 116 46)
 ⇒ (#(84 104 97 116 39 115) #(32) #(105 116) #(46))

二番めと三番目の例の入力は "That’s it." をコードポイント列にしたものです。

Function: string->grapheme-clusters string
Function: codepoints->grapheme-clusters sequence

{gauche.unicode} 与えられた文字列あるいはコードポイントシーケンス(コードポイントを要素とする <sequence>オブジェクト)から、graphemeクラスタのリストを返します。 各クラスタはそれぞれ、文字列あるいはコードポイントシーケンスで表現されます。

以下の手続きは上記のstring->words等の高レベル手続きを作る部品となる、 低レベル手続きです。

Function: make-word-breaker generator
Function: make-grapheme-cluster-breaker generator

{gauche.unicode} 文字かコードポイントを生成するジェネレータgeneratorを取り、 二つの値を返すジェネレータを返します。最初の値は元のジェネレータから受け取った 文字またはコードポイントで、二つめの値は、その文字またはコードポイントの直前に 単語もしくはgraphemeクラスタ境界があった時に#t、そうでない時に#fとなる 真偽値です。

ジェネレータgが文字列That's it.に含まれる文字を順に返す ジェネレータとすれば、作られるジェネレータの動作は次の通りです。

(define brk (make-word-breaker g))
(brk)  ⇒  #\T     and #t
(brk)  ⇒  #\h     and #f
(brk)  ⇒  #\a     and #f
(brk)  ⇒  #\t     and #f
(brk)  ⇒  #\'     and #f
(brk)  ⇒  #\s     and #f
(brk)  ⇒  #\space and #t
(brk)  ⇒  #\i     and #t
(brk)  ⇒  #\t     and #f
(brk)  ⇒  #\.     and #t
(brk)  ⇒  #<eof>  and #t

つまり、下図で^で示される箇所が単語境界となっています (空白字を_で表しています)。

  T h a t ' s _ i t .
 ^           ^ ^   ^ ^
Function: make-word-reader generator return
Function: make-grapheme-cluster-reader generator return

{gauche.unicode} generatorは文字またはコードポイントを生成するジェネレータで、 returnは文字またはコードポイントのリストを受け取り、オブジェクトを返す手続きです。 これらの手続きは、オブジェクト (単語またはgraphemeクラスタ) をひとつづつ生成する ジェネレータを返します。

ジェネレータgが文字列That's it.に含まれる文字を順に返す ジェネレータとすれば、作られるジェネレータの動作は次の通りです。

(define brk (make-word-reader g list->string))
(brk)  ⇒  "That's"
(brk)  ⇒  " "
(brk)  ⇒  "it"
(brk)  ⇒  "."
(brk)  ⇒  #<eof>

Next: , Previous: , Up: Unicodeユーティリティ   [Contents][Index]

9.35.3 フルセットの大文字小文字変換

Function: string-upcase string
Function: string-downcase string
Function: string-titlecase string
Function: string-foldcase string

[R6RS][R7RS char] {gauche.unicode} Converts the case of given string using language-independent full case folding defined by Unicode standard. They differ from srfi-13’s procedures with the same names (see 文字列のケース(大文字小文字)マッピング), which simply uses character-by-character case mapping. Notably, the length of resulting string may differ from the source string, and some conversions are sensitive to whether the character is at the word boundary or not. The word boundaries are determined according to UAX #29 text segmentation rules.

(string-upcase "straße")
 ⇒ "STRASSE"
(string-downcase "ΧΑΟΣΧΑΟΣ.ΧΑΟΣ. Σ.")
 ⇒ "χαοσχαοσ.χαος. σ."
(string-titlecase "You're talking about R6RS, right?")
 ⇒ "You're Talking About R6rs, Right?"
(string-foldcase "straße")
 ⇒ "strasse"
(string-foldcase "ΧΑΟΣΣ")
 ⇒ "χαοσσ"

Note that string-titlecase isn’t included in R7RS scheme.char module.

Function: codepoints-upcase sequence
Function: codepoints-downcase sequence
Function: codepoints-titlecase sequence
Function: codepoints-foldcase sequence

{gauche.unicode} Like string-upcase etc, but these work on a sequence of codepoints instead. Returns a sequence of the same type of the input.

(codepoints-upcase '#(115 116 114 97 223 101))
 ⇒ #(83 84 82 65 83 83 69)
Function: string-ci=? string1 string2 string3 …
Function: string-ci<? string1 string2 string3 …
Function: string-ci<=? string1 string2 string3 …
Function: string-ci>? string1 string2 string3 …
Function: string-ci>=? string1 string2 string3 …

[R7RS char] {gauche.unicode} Case-insensitive string comparison, using full-string case conversion.

Note that Gauche has builtin string-ci=? etc., which use character-wise case folding (see 文字列の比較). These are different procedures.

(string-ci=? "\u00df" "SS") ⇒ #t

Previous: , Up: Unicodeユーティリティ   [Contents][Index]

9.35.4 East asian width property

Function: char-east-asian-width char-or-codepoint

{gauche.unicode} The argument may be a character or a nonnegative integer of Unicode codepoint. Returns one of the symbols N (neutral), F (fullwidth), H (halfwidth), W (wide), Na (narrow), and A (ambiguous).

The meaning of this property is explained in Unicode standard annex #11, http://unicode.org/reports/tr11/.


Previous: , Up: Unicodeユーティリティ   [Contents][Index]