如何调整ICU的UnicodeString :: caseCompare(或获得相同的效果)

时间:2018-09-10 21:07:35

标签: c++ unicode icu

我对大小写折叠/不区分大小写的比较以及ICU的工作原理并不十分熟悉。

现在,我们有一些方法可以包装UnicodeString::caseCompare的各种重载,而我想更改它们以做一些稍有不同的事情:我想对点和无点进行比较(无论大小写)。

我知道ICU具有排序规则API,但是我不确定如何从与UnicodeString::caseCompare完全相同的规则开始,然后从那里进行修改。

1 个答案:

答案 0 :(得分:0)

我看不到使用C ++ UnicodeString类执行此操作的方法。

您必须从unicode/ustring.h下拉到较低级别的UChars字符串数组。特别是,u_strCaseCompare()可能是您想要的,或者将u_strcasecmp()与UnicodeString的getTerminatedBuffer()方法结合使用。

U_FOLD_CASE_EXCLUDE_SPECIAL_I选项的文档:

  

使用CaseFolding.txt中提供的修改后的一组映射来适当地处理点点I和不点点i,以适应突厥语(tr,az)。

认为,这意味着将它们视为等效。

通过实际测试进行编辑:

#include <stdio.h>
#include <stdlib.h>
#include <unicode/ustring.h>
#include <unicode/stringoptions.h>

void comp(const char *a, const char *b) {
  UChar s1[10], s2[10];
  UErrorCode err = U_ZERO_ERROR;
  int32_t len1, len2;
  u_strFromUTF8(s1, 10, &len1, a, -1, &err);
  u_strFromUTF8(s2, 10, &len2, b, -1, &err);
  printf("%s <=> %s: %d (Without special i) %d (With special i)\n", a, b,
         u_strCaseCompare(s1, len1, s2, len2, 0, &err),
         u_strCaseCompare(s1, len1, s2, len2, U_FOLD_CASE_EXCLUDE_SPECIAL_I, &err));
}

int main(void) {
  const char *lc_dotted_i = "i";
  const char *lc_dotless_i = "\u0131";
  const char *uc_dotless_i = "I";
  const char *uc_dotted_i = "\u0130";

  comp(lc_dotted_i, lc_dotless_i);
  comp(uc_dotted_i, uc_dotless_i);
  comp(lc_dotted_i, uc_dotted_i);
  comp(lc_dotless_i, uc_dotless_i);
  comp(lc_dotted_i, uc_dotless_i);
  comp(lc_dotless_i, uc_dotted_i);
  return 0;
}

结果:

i <=> ı: -200 (Without special i) -200 (With special i)
İ <=> I: 1 (Without special i) -200 (With special i)
i <=> İ: -1 (Without special i) 0 (With special i)
ı <=> I: 200 (Without special i) 0 (With special i)
i <=> I: 0 (Without special i) -200 (With special i)
ı <=> İ: 200 (Without special i) 200 (With special i)