アジョブジ星通信

進捗が出た頃に更新されるブログ。

SortKey を読み砕く

C# で StrConv を実装する - アジョブジ星通信
の最後の疑問に光が少し見えたのでメモ。

注意:完全には解決していません。

Thanks


Mono の怖い人に捕捉されました。ありがとうございます。

SortKey の取得方法

1. WinAPI を使う

LCMapString または LCMapStringExdwMapFlags 引数に LCMAP_SORTKEY(0x400) を突っ込んでやることで取得できます。

2. .NET Framework 標準ライブラリを使う

System.Globalization.CompareInfo.GetSortKey() で取得できます。 C#er ならこっちを選択!

構造

まずは、 "aBcDあぃウェォカ" の SortKey を取得してみます。コードはこんな感じ

new CultureInfo("ja-jp").CompareInfo.GetSortKey("aBcDあぃウェォカ").KeyData

戻り値(16進数)

0E 02 0E 09 0E 0A 0E 1A 22 02 22 03 22 04 22 05 22 06 22 0A 01 01 02 12 03 13 01 C6 C4 C6 C4 C4 FF 02 E4 E4 C4 C4 C4 C4 FF C5 C5 C5 C5 C4 FF 01 00

データはバイト配列で返ってきます。バイナリアンになった気分になれる。

まず、 01 で内容を 5 つに分けることができます。 Mono のドキュメントには level 1~5 と表記されています。

level 1

level 1 では、文字の種類とそのコード(その種類の中での順番?)が 1 バイトずつ入っています。この例では、アルファベットが 0E 、日本語が 22 ということがわかります。

level 2

出現条件が不明

level 3

Mono のドキュメントでも完全に調べきれているようではないですが、日本語以外の文字のフラグのようです。

02 が半角小文字、 03 が全角小文字、 12 が半角大文字、 13 が全角大文字でしょうか。

level 4

level 4 はひらがな、カタカナの種類を表します。内容は FF で 3 つに分けることができます。

1 つめは、大文字か小文字かです。大文字なら C6(Mono のドキュメントには E4 って書いてある…)、小文字なら C4 が返ってくるようです。数があっていないのは C6 は省略できるということでしょうか?

2 つめは、 02 で分けることができます。 02 の前には「voice mark」、「dash mark」なるものが入るらしいですが、句読点でも濁点でもないみたいです。なんなんだろう。 02 のあとは、 E4 がひらがな、 C4 がカタカナを表しています。

3 つめは、全角か半角かです。全角なら C5 、 半角なら C4 が返ってきます。最後は C4 が連続しているので省略されたようです。

level 5

理解できる気がしない

結論

これを使えば文字の比較ができるんだね!!!