Car*_*s00 6 c c++ unicode utf-8 unicode-normalization
我们编写一个C++应用程序,需要知道这个:
UTF8文本是否编码从字节到字符的内射映射,这意味着每个字符(字母...)只以一种方式编码?因此,例如字母'Ž'不能编码为3231和32119.
cel*_*chk 13
这在很大程度上取决于你认为的"信件".
UTF8基本上只是Unicode的一小部分.
基本上至少有三个级别:字节,代码点和Grapheme集群.根据特定编码,如UTF8,UTF16或UTF32,代码点可以编码为一个或多个字节.此编码是唯一的(因为所有替代方法都被声明为无效).但是,代码点并不总是字形,因为存在所谓的组合字符.这样的组合字符遵循基本字符,并且如其名称所示,与基本字符组合.例如,有一个组合字符U + 0308 COMBINING DIAERESIS,它将一个分音符(¨)置于前一个字母之上.因此,如果它遵循例如a(U + 0061 LATIN SMALL LETTER A),则结果是ä.然而,字母ä(U + 00E4 LATIN SMALL LETTER A WITH DIAERESIS)也有一个代码点,因此这意味着代码序列U + 0061 U + 0308和U + 00E4描述相同的字母.
因此,每个代码点都有一个有效的UTF 8编码(例如U + 0061是"\ 141",U + 0308是"\ 314\210"而U + 00e4是"\ 303\244",但字母ä是由代码点序列U + 0061 U + 0308编码,即以UTF8编码字节序列"\ 141\314\210"和单个代码点U + 00E4,即字节序列"\ 303\244".
更糟糕的是,由于Unicode制造商决定组合字母遵循基本字母而不是前面的字母,因此在看到下一个代码点之前,您无法知道字形是否完整(如果它不是组合代码点,那么信完了).
有效的 UTF-8确实唯一地编码每个字符.然而,存在所谓的超长序列,其符合通用编码方案,但是根据定义是无效的,因为可以仅使用最短序列来编码字符.
例如,UTF-8的衍生物称为修改的 UTF-8,它将NUL编码为超长序列,0xC0 0x80而不是0x00使编码与以null结尾的字符串兼容.
如果你问的是字形簇(即用户感知的字符)而不是字符,那么即使有效的UTF-8也是不明确的.但是,Unicode定义了几种不同的规范化形式,如果你将自己局限于规范化的字符串,那么UTF-8确实是单射的.
有些偏离主题:这是我想出的一些ASCII艺术,以帮助可视化角色的不同概念.垂直分离的是人类,抽象和机器级别.随意提出更好的名字......
[user-perceived characters]<-+
^ |
| |
v |
[characters] <-> [grapheme clusters] |
^ ^ |
| | |
v v |
[bytes] <-> [codepoints] [glyphs]<----------+
Run Code Online (Sandbox Code Playgroud)
回到主题:此图还显示了使用字节比较抽象字符串时可能出现的问题.特别是(假设UTF-8),程序员需要确保这一点
| 归档时间: |
|
| 查看次数: |
427 次 |
| 最近记录: |