Mega Code Archive

 
Categories / Delphi / Strings
 

Natural string compare

Title: Natural string compare Question: When sorting filename fx you meet names like pic1 pic 2 .. pic10 and so on... when sorted they end up like pic1 pic10 pic2 pic20 and so on... wouldn it be nice to sort it so it ends up like this pic1 .. pic9 pic10 pic11 and so on Answer: This routine will help you sort strings fx filenames more logical or natural. Example result after sorting pic001z3 pic1z001 pic01z02 pic01z02 pic1z001 pic001z3 pic1 pic1 pic10 pic2 pic2 pic3 pic20 pic10 pic3 pic20 function CompareNatural(s1, s2: String): Integer; // by Roy M Klever function ExtractNr(n: Integer; var txt: String): Int64; begin while (n = Length(txt)) and (txt[n] in ['0'..'9']) do n:= n + 1; Result:= StrToInt64Def(Copy(txt, 1, (n - 1)), 0); Delete(txt, 1, (n - 1)); end; var b: Boolean; begin Result:= 0; s1:= LowerCase(s1); s2:= LowerCase(s2); if (s1 s2) and (s1 '') and (s2 '') then begin b:= False; while (not b) do begin if ((s1[1] in ['0'..'9']) and (s2[1] in ['0'..'9'])) then Result:= Sign(ExtractNr(1, s1) - ExtractNr(1, s2)) else Result:= Sign(Integer(s1[1]) - Integer(s2[1])); b:= (Result 0) or (Min(Length(s1), Length(s2)) 2); if not b then begin Delete(s1,1,1); Delete(s2,1,1); end; end; end; if Result = 0 then begin if (Length(s1) = 1) and (Length(s2) = 1) then Result:= Sign(Integer(s1[1]) - Integer(s2[1])) else Result:= Sign(Length(s1) - Length(s2)); end; end;