gpt4 book ai didi

c# - 使用tocharArray()拆分汉字问题

转载 作者:行者123 更新时间:2023-12-05 09:28:42 28 4
gpt4 key购买 nike

我正在编写一个 C# 程序来像这样拆分汉字输入

textbox input ="大大大"
expected output =



代码是这样的

string aa="大大大";
foreach (char c in aa.ToCharArray()){
Console.WriteLine(c);
}

它适用于大多数角色。但是,对于某些字符,例如“𧜏”,我得到了这样的结果

textbox input = 𧜏大
output =



看起来程序无法处理这个字符

有什么解决办法吗?

最佳答案

长话短说:

解释

在 Unicode 中,the 𧜏 character有一个 U+2770F 的代码点,它超出了单个 16 位 UTF-16 值支持的范围(即 2 个字节,单个 .NET Char 值), 所以 UTF-16 使用 a pair of separate 16-bit values known as a surrogate pair to represent it :

using Shouldly;

String input = "𧜏";
Char[] chars = input.ToCharArray();
chars.Length.ShouldBe( 2 ); // 2*Char == 2*16-bits == 32 bits

Char.GetUnicodeCategory( chars[0] ).ShouldBe( UnicodeCategory.Surrogate );
Char.GetUnicodeCategory( chars[1] ).ShouldBe( UnicodeCategory.Surrogate );

因此,要像这样有意义地“拆分”字符串,您的程序需要知道代理对并且拆分一对。

下面的代码是一个简单的程序,它从字符串中提取每个 Unicode 代码点并将其添加到列表中。

String input = "大𧜏大";

// Don't forget to Normalize!
input = input.Normalize();

List<UInt32> codepoints = new List<UInt32>( capacity: 3 );

for( Int32 i = 0; i < input.Length; i++ )
{
Char c = input[i];

if( Char.GetUnicodeCategory( c ) == UnicodeCategory.Surrogate )
{
Char former = c;
Char latter = input[i+1];

// The former sibling has the upper 11 bits of the code-point (after 0x00D800).
// The latter sibling has the lower 10 bits of the code-point.

UInt32 hi = former;
UInt32 lo = latter;

UInt32 codepoint = ((hi - 0xD800) * 0x400) + (lo - 0xDC00) + 0x10000;

codepoints.Add( codepoint );

i += 1; // Skip the next char
}
else
{
codepoints.Add( c );
}
}

codepoint.Dump();
// [0] = 22823 == '大'
// [1] = 161551 == '𧜏'
// [2] = 22823 == '大'

请注意,对于非拉丁风格的字母表,将字符串拆分为离散字符、字形或字素的概念……很复杂。但一般来说,您希望将字符串拆分为离散的 Char 值 (Q.E.D.),但您也不应该将字符串拆分为代码点或者,您需要将字符串拆分为字形簇(相关字形的视觉分组,每个字形由它们自己的代码点表示,而代码点又可能是单个 .NET 16-位 Char 值,或 Char 值的代理对)。

幸运的是,.NET 已将此功能内置到 System.Globalization.TextElementEnumerator 中。

using System.Globalization;

String input = "大𧜏大".Normalize();

TextElementEnumerator iter = StringInfo.GetTextElementEnumerator( input );
while( iter.MoveNext() )
{
String graphemeCluster = iter.GetTextElement();
Console.WriteLine( graphemeCluster );
}

给我预期的输出:


𧜏

关于c# - 使用tocharArray()拆分汉字问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71169330/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com