在Windows资源pipe理器中如何获得sorting顺序?

综述:

  1. 我一直在寻找的术语似乎是“自然sorting”。
  2. 对于操作系统中的行为:

    • 对于Windows(版本> = XP),Windows资源pipe理器使用自然sorting。
    • 对于Linuxterminal:使用“ls -v”而不是简单的“ls”来自然sorting。
  3. 要在Delphi中编程,请使用StrCmpLogicalW Windows API进行自然sorting。

  4. 在Delphi&Kylix&Lazarus编程,使用手工function来自然sorting:
    • (1)Martin Pool自然sortingstring比较的Delphi包装。
      http://irsoft.de/web/strnatcmp-and-natsort-for-delphi
    • (2)davekeolle网站其他语言的alphanumsortingalgorithm代码。
      http://www.davekoelle.com/alphanum.html
    • (3)其他知识网页:
      http://www.codinghorror.com/blog/2007/12/sorting-for-humans-natural-sort-order.html
      http://objectmix.com/delphi/722211-natural-sorting-optimizing-working-solution.html
      http://groups.google.com/group/borland.public.delphi.language.delphi.general/browse_thread/thread/1141d49f8bbba577
      http://objectmix.com/delphi/401713-alphanumeric-sort-routine-delphi.html

==========================

下面的文件名将在Windows资源pipe理器中进行sorting,如下所示:

test_1_test.txt

test_2_test.txt

test_11_test.txt

test_12_test.txt

test_21_test.txt

test_22_test.txt

例如,如果我把它们放在一个TStringList实例中并调用Sort,sorting的顺序如下:

test_1_test.txt

test_11_test.txt

test_12_test.txt

test_2_test.txt

test_21_test.txt

test_22_test.txt

并且为了logging,上面的文件名将在Cygwin的rxvtterminal或Linux CentOS的xtermterminal(如CentOS)中订购,如下所示:

test_11_test.txt

test_12_test.txt

test_1_test.txt

test_21_test.txt

test_22_test.txt

test_2_test.txt

你能帮忙评论一下如何理解这种sorting行为的差异吗? 此外,是否有可能获得与Windows资源pipe理器相同的顺序? 任何build议表示赞赏!

PS:我的Windows语言环境设置为中文,但我认为英文语言环境也是如此。

StrCmpLogicalW能够处理数字,另一种选择是CompareString

感谢安德斯 – 答案是StrCmpLogicalW; 我还没有发现它在Delphi 2009源代码中的声明,所以我在下面的测试中自己声明:

type TMyStringList = class(TStringList) protected function CompareStrings(const S1, S2: string): Integer; override; end; function StrCmpLogicalW(P1, P2: PWideChar): Integer; stdcall; external 'Shlwapi.dll'; function TMyStringList.CompareStrings(const S1, S2: string): Integer; begin Result:= StrCmpLogicalW(PChar(S1), PChar(S2)); end; procedure TForm11.Button2Click(Sender: TObject); var SL: TMyStringList; begin SL:= TMyStringList.Create; try SL.Add('test_1_test.txt'); SL.Add('test_11_test.txt'); SL.Add('test_12_test.txt'); SL.Add('test_2_test.txt'); SL.Add('test_21_test.txt'); SL.Add('test_22_test.txt'); SL.Sort; Memo1.Lines:= SL; finally SL.Free; end; end;