I want to order a List of Strings with different Options. Options are:
- Alphabetical Sort or Logical Sort
- Case-Sensitive or not Case-Sensitive
- Ascending or Descending
I have all branches covered except for:
Case-Sensitive, Logical-Sort.
(Pretty much NatSort from php)
Now I am trying to find a Function that does what I need.
In order to get a not-case-sensitive logical order I implemented a call to the StrCmpLogicalW-Function in the shlwapi.dll
https://learn.microsoft.com/en-us/windows/desktop/api/shlwapi/nf-shlwapi-strcmplogicalw
However, I can not find a Case-Sensitive equivalent to StrCmpLogicalW.
I have copied a function that seemed promising from another onlineboard and played around with the Flags.
Original-Function:
function NatCompareText(const S1, S2: WideString): Integer;
begin
SetLastError(0);
Result:=CompareStringW(LOCALE_USER_DEFAULT,
NORM_IGNORECASE or
NORM_IGNORENONSPACE or
NORM_IGNORESYMBOLS,
PWideChar(S1),
Length(S1),
PWideChar(S2),
Length(S2)) - 2;
case GetLastError of
0: ;
//some ErrorCode-Handling
else
RaiseLastOSError;
end;
end;
From: https://www.delphipraxis.net/29910-natuerliche-sortierungen-von-strings.html
I tried to remove the Ignore-Case flag, but to no avail.
This is what I want as a result: http://php.fnlist.com/array/natsort
Input: array("Img12.png", "iMg10.png", "Img2.png", "Img1.png")
Output: array("Img1.png", "Img2.png", "Img12.png", "iMg10.png")
as opposed to: http://php.fnlist.com/array/natcasesort
Input: array("Img12.png", "iMg10.png", "Img2.png", "Img1.png")
Output: array("Img1.png", "Img2.png", "iMg10.png", "Img12.png")
UPDATE:
I have completed a first and very simple solution for case-sensitive natural sorting.
The reason I'm doing this is because I want to sort a Stringgrid on multiple Columns with different options for each Column specified.
In order to realize the natsort I am dissecting the strings into character parts and numerical parts and store each part in a stringlist.
both lists follow the pattern ('character-part','Numerical part','Character part',... and so on).
after splitting the strings I compare the list entries with each other. - numerical-parts are subtracted from each other (num1-num2) - for string-comparison I use CompareStr as opposed to AnsiCompareStr since it produces the same output as the php-natsort-function I linked to above.
if, at any point, the result of the comparison is different from 0 then no further comparison is needed and I escape the loop.
In my view, the solution is not completed yet since the topic of natural sorting is very broad, at the very least recognizing negative numbers still needs to be implemented.
Once I'm finished I will post my Code here for anyone who wants to be able to sort Stringgrids on multiple Columns and with different options for each column, since I wasn't able to find such code online yet.
I can not rely on 3rd-Party tools like RegEx for this. My main point of reference is currently this link:
SORT_DIGITSASNUMBERS
and removing theNORM_IGNORECASE
? Not sure if these work properly in XP, though. – MeritocracyStrCmpLogicalW
to apply the natural sorting, and if the result is that the strings are equal according to this comparison, call a second, case sensitive comparison method that doesn't have natural sorting. It may give undesired results when on a specific string position in both strings are different diacritics of the same character and having a different case, but those exceptional cases aside, this should get you very close to what you want. – HeallStringCompareW
ignore the case. It always sorts'iMG10.png' < 'Img12.png'
, even if theNORM_IGNORECASE
flag is not used. – Meritocracy