在C#中,StringInfoTextElementEnumerator类提供文本元素的方法和属性。
here,我们可以找到Text元素的定义。


  .NET Framework将text元素定义为以下文本单位:
  显示为单个字符,即字素。文字元素
  可以是以下任意一项:


是的,它说文本元素是.NET中的一个字素。我自己也测试了一些unicode字符,直到我测试了一个韩文字母“가”,这似乎是真的。

众所周知,某些Unicode字符由多个代码点组成。同样,我们可能会遇到代码点序列,这就是我使用StringInfoTextElementEnumerator而不是简单的String的原因。

StringInfoTextElementEnumerator可以判断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/

10-11 03:08