如何用ICU Collator实现与caseCompare(U_FOLD_CASE_DEFAULT)等效功能?
问题解决:用ICU Collator实现与UnicodeString.caseCompare等效的功能
原来的caseCompare方法本质是先对字符串做默认大小写折叠,再按Unicode代码点的顺序逐字符比较。而默认创建的Collator会采用Unicode排序算法(UCA),对不同符号的排序权重有特殊定义,这就是导致连字符和下划线比较结果相反的原因。
要实现完全等效的行为,需要将Collator配置为仅按代码点排序,同时保持大小写不敏感:
UErrorCode status = U_ZERO_ERROR; std::unique_ptr<icu::Collator> collator(icu::Collator::createInstance(status)); // 设置为 PRIMARY 强度忽略大小写,同时禁用所有特殊排序规则,改用代码点顺序 collator->setStrength(icu::Collator::PRIMARY); collator->setAttribute(UCOL_NUMERIC_COLLATION, UCOL_OFF, status); collator->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, status); collator->setAttribute(UCOL_FRENCH_COLLATION, UCOL_OFF, status); collator->setAttribute(UCOL_CASE_FIRST, UCOL_OFF, status); // 关键:设置排序规则为"direct",即严格按Unicode代码点顺序 collator->setAttribute(UCOL_COLLATION_TYPE, UCOL_DIRECT, status); return collator->compareUTF8(utf8Str1, utf8Str2, status);
关键说明:
UCOL_DIRECT属性会让Collator直接使用Unicode代码点的数值进行比较,和caseCompare的逐字符代码点比较逻辑对齐。- 关闭其他特殊排序属性(如数字排序、法语排序等),确保没有额外规则干扰比较结果。
PRIMARY强度已经包含了大小写不敏感的处理,和U_FOLD_CASE_DEFAULT的大小写折叠效果一致。
验证后,配置后的Collator对"test-test"和"test_test"的比较结果会和caseCompare一致——因为连字符(U+002D)的代码点小于下划线(U+005F),所以"test-test" < "test_test"。
内容的提问来源于stack exchange,提问作者meerkat
相关产品推荐
相关产品推荐

