You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何从XML Unicode字符数据库提取Unicode规范化表?属性选择困惑

解决Unicode规范化表构建的属性选择问题

首先,你找错属性组啦!NF(C|D|KC|KD)_QC 这类属性的作用正如你所说,只是快速判断字符串是否已经符合对应规范化形式,它们不会给出具体的码点映射关系,用来构建规范化表肯定行不通。

要构建Unicode规范化(比如NFD、NFC、NFKD、NFKC)所需的映射表,你需要关注以下这些核心属性和数据文件:

1. 规范化分解与组合的核心属性

  • Canonical Decomposition(Canonical_Combining_Class + Decomposition_Mapping
    • Canonical_Combining_Class:决定字符的组合顺序,非0值表示该字符是组合字符,需要和前面的基字符组合。
    • Decomposition_Mapping:这才是你需要的核心属性!它会给出字符的规范化分解结果——比如带重音的字符会分解为基字符+重音符号,或者兼容字符分解为对应的标准字符(比如全角数字分解为半角数字)。
    • 注意:Decomposition_Mapping里的<compat>标记对应NFKD/NFKC的兼容分解,没有标记的是NFD/NFC的规范分解。
  • Canonical Composition Exclusions:有些字符虽然可以分解,但不会被反向组合(比如某些特殊的带重音字符),这个列表需要用来处理NFC/NFKC的组合逻辑。

2. 大小写折叠的相关属性

如果你的脚本还包含大小写折叠功能,除了常见的Lowercase_MappingUppercase_MappingTitlecase_Mapping,还要注意:

  • Case_Folding属性:它提供了更全面的大小写映射,包括一些特殊语言的折叠规则(比如德语的ß对应SS,或者土耳其语的I/i规则),比单纯的上下映射更适合做大小写折叠表。

3. 获取这些属性的正确方式

你不需要自己从UAX#44里抠属性定义,直接用Unicode官方提供的UnicodeData.txtCaseFolding.txt这两个数据文件就够了:

  • UnicodeData.txt:包含了所有字符的Decomposition_MappingCanonical_Combining_Class、上下映射等核心属性,每一行是一个字符的完整数据,用分号分隔。
  • CaseFolding.txt:专门存放大小写折叠的映射规则,包含简单折叠和全折叠两种类型。

举个C语言处理的简化示例,读取UnicodeData.txt时可以按分号分割字段,提取关键信息:

// 示例:解析UnicodeData.txt的一行(简化版)
char line[1024];
FILE *fp = fopen("UnicodeData.txt", "r");
if (!fp) { /* 处理文件打开失败 */ }

while (fgets(line, sizeof(line), fp)) {
    char *token = strtok(line, ";");
    int field_idx = 0;
    char code_point[10], decomp_mapping[256], combining_class[10];
    
    while (token != NULL) {
        switch(field_idx) {
            case 0: strncpy(code_point, token, sizeof(code_point)-1); break; // 字符码点
            case 2: strncpy(combining_class, token, sizeof(combining_class)-1); break; // 组合类
            case 4: strncpy(decomp_mapping, token, sizeof(decomp_mapping)-1); break; // 分解映射
        }
        field_idx++;
        token = strtok(NULL, ";");
    }
    // 这里可以处理分解映射:判断是否带<compat>标记,提取分解后的码点列表等
}
fclose(fp);

最后总结

你之前的问题就是误把“规范化检查属性”当成了“规范化映射属性”,换用Decomposition_MappingCanonical_Combining_Class这些属性,再结合官方的Unicode数据文件,就能顺利构建出你需要的规范化和大小写折叠表啦。

内容的提问来源于stack exchange,提问作者user4302383

火山引擎 最新活动