mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 09:09:19 +02:00
* NaturalCompare
git-svn-id: trunk@32818 -
This commit is contained in:
parent
353f5340dc
commit
bdde398a98
@ -55,6 +55,8 @@ Function AnsiReverseString(const AText: AnsiString): AnsiString;inline;
|
|||||||
Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
|
Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
|
||||||
Function RandomFrom(const AValues: array of string): string; overload;
|
Function RandomFrom(const AValues: array of string): string; overload;
|
||||||
Function IfThen(AValue: Boolean; const ATrue: string; const AFalse: string = ''): string; overload;
|
Function IfThen(AValue: Boolean; const ATrue: string; const AFalse: string = ''): string; overload;
|
||||||
|
function NaturalCompareText (const S1 , S2 : string ): Integer ;
|
||||||
|
function NaturalCompareText(const Str1, Str2: string; const ADecSeparator, AThousandSeparator: Char): Integer;
|
||||||
|
|
||||||
{ ---------------------------------------------------------------------
|
{ ---------------------------------------------------------------------
|
||||||
VB emulations.
|
VB emulations.
|
||||||
@ -434,6 +436,160 @@ begin
|
|||||||
result:=afalse;
|
result:=afalse;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function NaturalCompareText(const Str1, Str2: string; const ADecSeparator, AThousandSeparator: Char): Integer;
|
||||||
|
{
|
||||||
|
NaturalCompareBase compares strings in a collated order and
|
||||||
|
so numbers are sorted too. It sorts like this:
|
||||||
|
|
||||||
|
01
|
||||||
|
001
|
||||||
|
0001
|
||||||
|
|
||||||
|
and
|
||||||
|
|
||||||
|
0
|
||||||
|
00
|
||||||
|
000
|
||||||
|
000_A
|
||||||
|
000_B
|
||||||
|
|
||||||
|
in a intuitive order.
|
||||||
|
}
|
||||||
|
var
|
||||||
|
Num1, Num2: double;
|
||||||
|
pStr1, pStr2: PChar;
|
||||||
|
Len1, Len2: integer;
|
||||||
|
TextLen1, TextLen2: integer;
|
||||||
|
TextStr1: string = '';
|
||||||
|
TextStr2: string = '';
|
||||||
|
i: integer;
|
||||||
|
j: integer;
|
||||||
|
|
||||||
|
function Sign(const AValue: Integer): integer;inline;
|
||||||
|
|
||||||
|
begin
|
||||||
|
If Avalue<0 then
|
||||||
|
Result:=-1
|
||||||
|
else If Avalue>0 then
|
||||||
|
Result:=1
|
||||||
|
else
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function IsNumber(ch: char): boolean;
|
||||||
|
begin
|
||||||
|
Result := ch in ['0'..'9'];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function GetInteger(var pch: PChar; var Len: integer): double;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
while (pch^ <> #0) and IsNumber(pch^) do
|
||||||
|
begin
|
||||||
|
Result := Result * 10 + Ord(pch^) - Ord('0');
|
||||||
|
Inc(Len);
|
||||||
|
Inc(pch);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure GetChars;
|
||||||
|
begin
|
||||||
|
TextLen1 := 0;
|
||||||
|
while not ((pStr1 + TextLen1)^ in ['0'..'9']) and ((pStr1 + TextLen1)^ <> #0) do
|
||||||
|
Inc(TextLen1);
|
||||||
|
SetLength(TextStr1, TextLen1);
|
||||||
|
i := 1;
|
||||||
|
j := 0;
|
||||||
|
while i <= TextLen1 do
|
||||||
|
begin
|
||||||
|
TextStr1[i] := (pStr1 + j)^;
|
||||||
|
Inc(i);
|
||||||
|
Inc(j);
|
||||||
|
end;
|
||||||
|
|
||||||
|
TextLen2 := 0;
|
||||||
|
while not ((pStr2 + TextLen2)^ in ['0'..'9']) and ((pStr2 + TextLen2)^ <> #0) do
|
||||||
|
Inc(TextLen2);
|
||||||
|
SetLength(TextStr2, TextLen2);
|
||||||
|
i := 1;
|
||||||
|
j := 0;
|
||||||
|
while i <= TextLen2 do
|
||||||
|
begin
|
||||||
|
TextStr2[i] := (pStr2 + j)^;
|
||||||
|
Inc(i);
|
||||||
|
Inc(j);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (Str1 <> '') and (Str2 <> '') then
|
||||||
|
begin
|
||||||
|
pStr1 := PChar(Str1);
|
||||||
|
pStr2 := PChar(Str2);
|
||||||
|
Result := 0;
|
||||||
|
while not ((pStr1^ = #0) or (pStr2^ = #0)) do
|
||||||
|
begin
|
||||||
|
TextLen1 := 1;
|
||||||
|
TextLen2 := 1;
|
||||||
|
Len1 := 0;
|
||||||
|
Len2 := 0;
|
||||||
|
while (pStr1^ = ' ') do
|
||||||
|
begin
|
||||||
|
Inc(pStr1);
|
||||||
|
Inc(Len1);
|
||||||
|
end;
|
||||||
|
while (pStr2^ = ' ') do
|
||||||
|
begin
|
||||||
|
Inc(pStr2);
|
||||||
|
Inc(Len2);
|
||||||
|
end;
|
||||||
|
if IsNumber(pStr1^) and IsNumber(pStr2^) then
|
||||||
|
begin
|
||||||
|
Num1 := GetInteger(pStr1, Len1);
|
||||||
|
Num2 := GetInteger(pStr2, Len2);
|
||||||
|
if Num1 < Num2 then
|
||||||
|
Result := -1
|
||||||
|
else if Num1 > Num2 then
|
||||||
|
Result := 1
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Result := Sign(Len1 - Len2);
|
||||||
|
end;
|
||||||
|
Dec(pStr1);
|
||||||
|
Dec(pStr2);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
GetChars;
|
||||||
|
if TextStr1 <> TextStr2 then
|
||||||
|
Result := WideCompareText(UTF8Decode(TextStr1), UTF8Decode(TextStr2))
|
||||||
|
else
|
||||||
|
Result := 0;
|
||||||
|
end;
|
||||||
|
if Result <> 0 then
|
||||||
|
Break;
|
||||||
|
Inc(pStr1, TextLen1);
|
||||||
|
Inc(pStr2, TextLen2);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Num1 := Length(Str1);
|
||||||
|
Num2 := Length(Str2);
|
||||||
|
if (Result = 0) and (Num1 <> Num2) then
|
||||||
|
begin
|
||||||
|
if Num1 < Num2 then
|
||||||
|
Result := -1
|
||||||
|
else
|
||||||
|
Result := 1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function NaturalCompareText (const S1 , S2 : string ): Integer ;
|
||||||
|
begin
|
||||||
|
Result := NaturalCompareText(S1, S2,
|
||||||
|
DefaultFormatSettings.DecimalSeparator,
|
||||||
|
DefaultFormatSettings.ThousandSeparator);
|
||||||
|
end;
|
||||||
|
|
||||||
{ ---------------------------------------------------------------------
|
{ ---------------------------------------------------------------------
|
||||||
VB emulations.
|
VB emulations.
|
||||||
---------------------------------------------------------------------}
|
---------------------------------------------------------------------}
|
||||||
|
Loading…
Reference in New Issue
Block a user