在C#中,StringInfo
和TextElementEnumerator
类提供文本元素的方法和属性。
然后here,我们可以找到文本元素的定义。
.NET Framework将text元素定义为以下文本单位: 显示为单个字符,即字素。文字元素 可以是以下任意一种:
是的,它表示文本元素是.NET中的字素。我还亲自测试了一些unicode字符,直到我测试了一个韩文字母“ 가”之前,这确实是真的。
众所周知,某些Unicode字符由多个代码点组成。同样,我们可能会遇到代码点序列,这就是我使用StringInfo
和TextElementEnumerator
而不是简单的String
的原因。
StringInfo
和TextElementEnumerator
可以判断Char
是否是正确的代理对。正如预期的那样,由多个代码点组成的Unicode字符“ \ u0061 \ u0308”被识别为一个文本元素。但是对于“ \ u1100 \ u1161”,它并不能说它也是一个文本元素。
“ \ u1100”是前导字母“ㄱ”,而“ \ u1161”是元音字母“ㅏ”。它们可以是单独的字符,并可以像我在此处编写的那样显示给用户,您现在可以看到它们。但是,如果将它们一起使用,它们将被呈现为一个字符“가”而不是“ㄱㅏ”。
有两种方式来表示朝鲜语字符“가”:
大多数情况下使用前者。坦白说,后者很少使用。我完全无法想象何时使用它。 无论如何,第一个字母只是一个预组合字母,第二个字母是 Lead 和 Vowel 的序列,被视为一个字符。渲染时,它们看起来完全一样,并且两者实际上在规范上是等效的。 同样,以下行在C#中返回true:
"\u1100\u1161".Normalize() == "\uAC00"
我想知道为什么当C#认为Normalize()
并不是一个完整的文本元素时,这里的效果很好。
我以为它与.NET的版本有关,但事实并非如此。甚至在Mono中也会发生这种事情。
我也用ICU
对此进行了测试,它可以正确将“ \ u1100 \ u1161”视为一个字素!
我最初以为StringInfo
和TextElementEnumerator
可以在某些简单情况下消除对 ICU4C 的需求,所以现在我很失望。.
这是我的问题:
我在这里做错什么了吗?
或
.NET中的文本元素不是用户在ICU中所感知的字符吗?
答案 0 :(得分:2)
这里的基本问题是,根据韩国标准KS X 1026,两个jams ㄱ
和ㅏ
与它们的组合形式가
不同。实际上,此确切示例已在官方标准中使用(请参见6.2节)。
长话短说,Microsoft尝试遵循该标准,但其他操作系统和应用程序不一定要遵循该标准。因此,您可以从其他软件/平台上获得“格式错误”的内容,这些内容在Windows / .NET中似乎被错误地解析,即使在这些平台上被“正确”地解析也是如此。
您要么需要首先确保您的数据正确形成(鉴于 de-facto 标准完全忽略了 official 标准,但不太可能)否则您将需要使用ICU(或类似的库)来处理这些情况。