Title

Windowsのファイル名ソート順の再現が難しい件(StrCmpLogicalW)

最近「ComicGlassのソートがWindowsの並びと違う」とご意見を頂きました。

WindowsXP以降ではファイル名のソート順が数値などを解釈する自然な並びになるようになっています。
よって単純なコードの比較とは違う結果になります。

よく説明されるのは、
20string
2string
3string
というソート順だったのが
2string
3string
20string
という感じになることでしょうか。

WindowsであればStrCmpLogicalW()というAPIを呼び出すとこのソートが行われます。
Windows以外の環境でこのソートを再現する方法は、検索するといくつか提案されていますが、どうも結果が違います。
公式な仕様が見つかればいいんですが、どうも見つかりません。

そこで、それを再現すべくそもそもWindowsがどのようにソートしているか実験してみました。
(特に海外のサイトの情報はUnicode文字に関する配慮がほとんどされてない事が多いので)

結論から言うと、StrCmpLogicalWを再現するのって無理ゲーなんじゃないかと・・・。
いい方法あったら是非教えてください。

とりあえず、以下調査結果でございます。

・StrCmpLogicalWは記号、数値、その他文字の順で並ぶ

ASCIIやUnicodeでは「!」は「0~9」より前にあるが「;」などは数値より後です。
しかしながらWindowsでは「;」などの記号も数値より前に並びます。

(Unicodeコード順)
!test.txt
0test.txt
;test.txt

(Windows)
!test.txt
;test.txt
0test.txt

というわけで、その文字が「記号」であるか「数値」であるか「その他文字」であるかを区別しているようです。

そこで問題になるのが、何が記号で何が記号でないか。

(記号になる例)
!
;
®
µ
§
»

(記号にならない一例)
¼
À

うーん。規則性がわからん。
プログラムを組んでStrCmpLogicalWで実際に試してみたのですが、かなり後ろの方のコードまで記号扱いになるものとと文字扱いになるものが入り乱れています。
どうもUnicodeコンソーシアムが規定するUNICOD文字一覧表に記号かどうかの情報があるようです。
つまりUnicodeとして記号かどうかで判断されており、それは規則性などなく全一覧を知らないとどうにもならない。
まぁ、それだけなら全コードの情報を持っておけばいいのですが・・・

・・・しかし!
Windowsが知らない新しいUnicodeは正しく解釈していないような気がします・・・。

例えばU+2639(☹)、U+263A(☺)、U+263B(☻)は記号扱いですが、その他顔文字は記号になりません。
もしかしたらWindowsではサロゲートペアが正しく処理されていないだけかもしれません・・・。

これは心が折れますね・・・!

・StrCmpLogicalWは全角の記号も半角と記号と同じ扱いになる

同じ記号の場合は全角の方が後になる。
・・・ってことは正準等価性を使った正規化してるんでしょうかね?
その説を支持する結果として「»」が「§」よりも前に並ぶんですよね。コードは後ろなのに。

しかし後述しますが、数値で混在すると別々に評価されるっぽい。つまり単純に先に正規化しても駄目と・・・。

・StrCmpLogicalWは数字が並んでいる場合はまとめて1つの意味付けがされる

0001.txt
2.txt
003.txt

これはファイルに0から順に名前つけて桁が増えた時に変な順番になるのを防げます。

・StrCmpLogicalWは20桁以上の数値は数値として扱わない

符号なし64bitで表せる値の最大値は18,446,744,073,709,551,616で20桁なので、20桁目からオーバーフローします。
よって、Windowsも64bit演算で扱える最大値の19桁まで取り扱うようになっていると思われます。
これは実装が楽で助かります。

・StrCmpLogicalWは全角の0~9も数字として扱われる
 ・ただし半角全角混在の場合はそうならない。何故だ・・。

情報求む・・・・!

とりあえずASCIIコードにある記号だけ記号として解釈し、数値は19桁まで数値として認識する、という方法でだいたい近い結果にはなります。一致はしませんが。

Leave a Reply

E-Mail (will not be published)
Comment
*

カレンダー

2024年3月
 123
45678910
11121314151617
18192021222324
25262728293031

▲Pagetop