Существует ли код Delphi для алгоритма сортировки Unicode (UCA)? - PullRequest
2 голосов
/ 10 февраля 2012

Подборка в соответствии с Техническим стандартом Unicode # 10 (UCA), которая отличается от того, чтобы быть совместимой с Unicode, если вам интересно об этом, подразумевает не только упорядочение / сортировку, но и сравнение, вопросы "равняется ли строка 1в строку 2 ".Иногда кодовые точки, которые не имеют одно и то же значение в обеих строках, должны рассматриваться как равные для сопоставления и сравнения, по крайней мере, это подразумевается в этом сообщении в блоге , которое говорит с точки зрения стандартной библиотеки Perl.

Что я хочу знать, так это: (a) Delphi XE2 уже полностью реализует спецификацию Unicode Collation Spec и (b) если нет, делает ли это сторонняя библиотека?

Пример кода:

Str1 := Chr($212B);
Str2 := Chr($C5);
n := CompareStr(Str1,Str2); // in delphi this is not zero, under UCA rules, should be 0.

В соответствии со спецификацией сопоставления Unicode при сопоставлении Unicode все сравниваемые кодовые точки должны учитываться при сравнении.Это не имеет смысла с бинарной точки зрения, и поэтому я рад, что ни CompareStr в Delphi, ни cmp в perl (из связанной статьи) не загрязнены сбоями Unicode, но что, если вы хотите сделать Unicode-совместимымсопоставление в Delphi, как библиотека perl Unicode :: Collation?Как?

Обновление AnsiCompareStr будет вызывать Win32 CompareString и будет обрабатывать некоторые специфичные для локали случаи, такие как приведенные выше, и из чтения в Интернете, классического поведения Unicode для сопоставления Windows иUCA сходятся медленно, но не полностью, и похоже, что UCA изменили, сделав его более похожим на параметры сортировки Windows.

1 Ответ

7 голосов
/ 10 февраля 2012

(а) № Дельфи AnsiCompareStr и со.оберните функцию Win32 CompareString , которая не следует алгоритму сопоставления Unicode.

(b) Проект ICU поддерживает его, но оболочка Delphi, ICU4PAS , не обновлялась с 2007 года.

Томожет быть, вам не нужно, хотя.Причина, по которой вы видите свое поведение, заключается в том, что вы используете CompareStr вместо AnsiCompareStr .Не-ANSI версия написана в asm в SysUtils, сравнивает символ за символом и не учитывает эквивалентность или комбинацию символов.Версия без учета регистра CompareText также работает только с az.Версии ANSI вызывают функцию CompareString для внутреннего использования, которая учитывает локали и обрабатывает все эти случаи.

Обратите внимание, что это верно только для подпрограмм в SysUtils.В StrUtils.pas не-ANSI версии являются просто встроенными оболочками вокруг ANSI-версий, поэтому все они знают о локали.

...