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