13

Unicode 中的“组合字符”</a> 和“字形扩展器”</a> 有什么区别?

据我所知,它们似乎在做同样的事情——尽管字素扩展器的集合大于组合字符的集合。我显然在这里遗漏了一些东西。为什么要区分?


Unicode 标准,第 3 章,D52

  • 组合字符:具有组合标记(M)的一般类别的字符。
  • 组合字符由具有间距组合标记 (Mc)、非间距标记 (Mn) 和封闭标记 (Me) 的常规类别值的所有字符组成。
  • 所有具有非零规范组合类的字符都是组合字符,但情况并非如此:存在具有零规范组合类的组合字符。
  • 私有字符 (Co) 是否解释为组合字符由实现决定。
  • 这些字符通常不会单独使用,除非它们被描述。它们包括诸如口音、变音符号、希伯来语点、阿拉伯元音符号和印度语 matras 等字符。
  • 组合字符的图形定位取决于最后一个前面的基本字符,除非它们被一个既不是组合字符也不是零宽度连接符或零宽度非连接符的字符分隔。据说组合字符适用于该基本字符。
  • 可能没有这样的基本字符,例如当组合字符位于文本开头或跟随控制或格式字符时 - 例如,回车符、制表符或左右标记。在这种情况下,组合字符称为孤立组合字符。
  • 有孤立的组合字符或当一个进程无法进行图形组合时,进程可能会呈现一个没有图形组合的组合字符;也就是说,它可以将其呈现为就好像它是一个基本字符一样。
  • 组合字符的代表图像在代码图中用虚线圆圈表示。当与前面的基本字符以图形组合形式呈现时,该基本字符旨在出现在虚线圆圈所占据的位置。

Unicode 标准,第 3 章,D59

  • Grapheme 扩展器:具有Grapheme_Extend属性的字符。
  • 字形扩展字符由所有非间距标记、零宽度连接符、零宽度非连接符、U+FF9E、U+FF9F 和少量间距标记组成。
  • 字素扩展器主要可以被认为是一种非间距图形标记,应用于另一个间距字符的上方或下方。零宽度连接器和零宽度非连接器被正式定义为字素扩展器,因此它们的存在不会破坏其他字素扩展器的序列。
  • 少数具有 Grapheme_Extend 属性的间距标记都是双部分组合标记的第二部分。
  • 根据定义,具有 Grapheme_Extend 属性的字符集和具有 Grapheme_Base 属性的字符集是不相交的。
4

3 回答 3

6

实际使用的不同之处在于,组合字符被定义为通用类别,用于对字符进行粗略分类,而字素扩展器主要用于UAX#29 文本分割

编辑:既然你提供了赏金,我可以详细说明一下。

组合字符是不能用作独立字符但必须与另一个字符组合使用的字符。它们用于定义组合字符序列

字形扩展器在 Unicode 3.2中引入,用于Unicode 技术报告 #29:文本边界(当时处于提议状态,现在称为Unicode 标准附件 #29:Unicode 文本分割)。主要用途是定义字形簇。字素簇基本上是用户感知的字符。根据 UAX #29:

字素簇边界对于排序规则、正则表达式、UI 交互(例如鼠标选择、箭头键移动、退格)、垂直文本的分割、首字母样式的边界识别以及计算文本中的“字符”位置非常重要。

主要区别在于字形扩展器不包括大多数间距标记(该集实际上小于组合字符集)。大多数间隔标记是亚洲文字的元音符号。在这些脚本中,有时通过修改辅音字符来编写元音。如果这种修改占用了水平空间(间距标记),它曾经被视为一个单独的用户感知字符并形成一个新的(传统)字素簇。在后来的 UAX #29 版本中,这一点得到了改变,并引入了扩展的字形簇,其中大多数但不是所有的间距标记都不会破坏簇。

我认为标准中的关键语句是:“字素扩展器可以主要被认为是一种在另一个间距字符上方或下方应用的非间距图形标记。” 另一方面,组合字符还包括应用于left 或 right的间距标记。不过也有一些例外(参见属性 Other_Grapheme_Extend)。

例子

U+0995 孟加拉语字母 KA :

ক</h1>

U+09C0 BENGALI VOWEL SIGN II(组合字符,但没有字素扩展):

两者的结合:

কী

这是由两个遗留字素簇组成的单个组合字符序列。元音符号不能单独使用,但它仍然算作遗留字素簇。例如,文本编辑器可以允许将光标放在两个字符之间。

像这样不扩展字素的组合字符有 300 多个,而没有组合但扩展字素的字符有 4 个。

于 2014-02-14T11:09:45.790 回答
3

我已经在 Unicode 邮件列表上发布了这个问题并得到了更多回复。我会在这里发布其中的一些。

汤姆·格维克写道:

我不是 Unicode 这方面的专家,但我知道“字素扩展器”是字符属性的更好区分,旨在用于某些特定和复杂的过程,如字素破坏。您可能会发现这篇博客文章有助于了解它的作用: http ://useless-factor.blogspot.com/2007/08/unicode-implementers-guide-part-4.html

PS在我看来,StackOverflow 上 nwellnhof 的回答很好地解释了这个问题。

菲利普·维迪写道:

许多字素扩展器不是“组合字符”。由于遗留原因(非常弱的“一般类别”属性),组合字符以这种方式分类,并且该属性在规范上是稳定的。同样,大多数组合字符都具有非零组合类,并且为了规范化而对它们进行了稳定化。

字形扩展器包括的字符也不是组合字符而是控件(例如连接符)。在某些脚本中,一些图形簇也更复杂(在基本字符之前编码了扩展器;并且它们不能归类为组合字符,因为组合字符总是在基本字符之后编码)

由于遗留原因(以及与旧标准的往返兼容性),并非所有脚本都使用 UCS 字符模型使用组合字符进行编码。(例如泰语脚本;不遵循“逻辑”编码顺序;而是遵循 TIS-620 中使用的模型和基于它的其他标准;包括 Windows 和 *nix/*nux)。

理查德·沃丁厄姆写道:

间距组合标记(类别 Mc)通常不是字素扩展器。包含的大部分都包含在内,因此“遗留字素集群” http://www.unicode.org/reports/tr29/tr29-23.html之间的边界在规范等价下是不变的。有六个字素扩展符不是非间距 (Mn) 或封闭 (Me),并且此规则不需要:ZWNJ、ZWJ、U+302E HANGUL SINGLE SINGLE DOT TONE MARK U+302F HANGUL DOUBLE DOT TONE MARK U+FF9E HALFWIDTH KATAKANA有声标记 U+FF9F 半宽片假名 半声标记

我可以看到它有时会对 ZWNJ 和 ZWJ 以及以前的基本字符有所帮助。出于规范等效的原因,包含全角声标 U+3099 和 U+309A,因此包含它们的半角版本是有意义的。

我实际上没有看到包含 U+302E 和 U+302F 的逻辑。如果您要鼓励在一系列 3 个非间距标记之前强制输入错误基本字符的人重新输入该批次,那么您也可以对 Hangul 音调标记执行相同操作。

于 2014-02-22T08:23:34.430 回答
1

请允许我引用 Yannis Haralambous 的Fonts and Encodings,第 116f 页:

这个想法是脚本或符号系统有时过于精细地划分为字符。而且,当我们将结构切割成字符时,就无法将它们重新组合在一起以重建更大的字符。例如,加泰罗尼亚语有连字“ŀl”。该连字被编码为两个 Unicode 字符:一个“ŀ” 0x0140 latin small letter l with middle dot和一个普通的“l”。但这种划分可能并不总是我们想要的。
假设我们希望在这个连字上加一个抑扬符,就像我们可能希望对连字“œ”和“æ”做的那样。如何在 Unicode 中做到这一点?为了允许用户在扮演新字符角色的结构中构建字符,Unicode 引入了三个新属性(字形基础、字形扩展, 字形链接)和一个新字符: 0x034F combining grapheme joiner.

所以在我看来,这意味着字形扩展器用于(例如)对本身由多个字符组成的字符应用重音符号。

于 2014-02-13T08:45:13.013 回答