char c = 'Â';
string character_name;
if (!charname_map.TryGetValue( c, out character_name ))
character_name = "<Character Name Missing>"; //character not found in map
//character_name should now contain "LATIN CAPITAL LETTER A WITH CIRCUMFLEX";
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
internal class Program
{
// u_charName() ICU API that comes with Windows since Fall Creators Update (Version 1709 Build 16299)
// https://docs.microsoft.com/windows/win32/intl/international-components-for-unicode--icu-
// https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/uchar_8h.html#a2d90141097af5ad4b6c37189e7984932
// u_charName() returns the "modern" name of a Unicode character; or the name
// that was defined in Unicode version 1.0, before the Unicode standard merged
// with ISO-10646; or an "extended" name that gives each Unicode code point a
// unique name.
[DllImport("icuuc.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, ExactSpelling = true)]
internal extern static int u_charName(int code, UCharNameChoice nameChoice, IntPtr buffer, int bufferLength, out int errorCode);
public enum UCharNameChoice
{
UNICODE_CHAR_NAME,
UNICODE_10_CHAR_NAME,
EXTENDED_CHAR_NAME,
CHAR_NAME_ALIAS,
CHAR_NAME_CHOICE_COUNT
}
private static int CharName(int code, UCharNameChoice nameChoice, out string name)
{
const int nSize = 255;
IntPtr resPtr = Marshal.AllocCoTaskMem(nSize);
try
{
int error;
int nResult = u_charName(code, nameChoice, resPtr, nSize, out error);
if (error != 0)
{
nResult = -1;
name = null;
}
else
name = Marshal.PtrToStringAnsi(resPtr);
return nResult;
}
finally
{
Marshal.FreeCoTaskMem(resPtr);
}
}
private static string FormatUniChar(int ch)
{
string chName;
CharName(ch, UCharNameChoice.EXTENDED_CHAR_NAME, out chName);
return $"U+{ch:X4} {chName}";
}
static void Main(string[] args)
{
string value = "Hello World! 😍 ❤️";
List<int> rawUtf32list = new List<int>();
for (int i = 0; i < value.Length; i++)
{
if (Char.IsHighSurrogate(value[i]))
{
rawUtf32list.Add(Char.ConvertToUtf32(value[i], value[i + 1]));
i++;
}
else
rawUtf32list.Add((int)value[i]);
}
Console.WriteLine(value);
foreach (int utf32Char in rawUtf32list)
{
Console.WriteLine(FormatUniChar(utf32Char));
}
}
}
}
在我的系统上打印:
U+0048 LATIN CAPITAL LETTER H
U+0065 LATIN SMALL LETTER E
U+006C LATIN SMALL LETTER L
U+006C LATIN SMALL LETTER L
U+006F LATIN SMALL LETTER O
U+0020 SPACE
U+0057 LATIN CAPITAL LETTER W
U+006F LATIN SMALL LETTER O
U+0072 LATIN SMALL LETTER R
U+006C LATIN SMALL LETTER L
U+0064 LATIN SMALL LETTER D
U+0021 EXCLAMATION MARK
U+0020 SPACE
U+1F60D SMILING FACE WITH HEART-SHAPED EYES
U+0020 SPACE
U+2764 HEAVY BLACK HEART
U+FE0F VARIATION SELECTOR-16
7条答案
按热度按时间fdbelqdn1#
现在比以往任何时候都容易,因为nuget中有一个名为Unicode Information的包
有了这个,你就可以调用:
zysjyyx42#
这里有一个可以立即实现的解决方案,就像复制/粘贴/编译。
首先,在这里下载Unicode数据库(UCD):http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
接下来,将以下代码添加到项目中,以读取UCD并创建一个Dictionary,用于查找.NET字符值的名称:
UnicodeData.txt文件采用UTF-8编码,每个Unicode码位包含一行信息。每行包含一个用分号分隔的字段列表,其中第一个字段是十六进制的Unicode码位(不带前缀),第二个字段是字符名称。有关文件和每行包含的其他字段的信息,请参阅:有关UCD格式的信息可在此处找到:http://www.unicode.org/reports/tr44/#Format_Conventions
使用上面的代码构建字符到字符名称的Map后,只需使用以下代码从Map中检索它们:
我建议将UnicodeData.txt文件嵌入到您的应用程序资源中,并将此代码 Package 到一个类中,该类在静态初始化器中加载并解析文件一次。为了使代码更具可读性,您可以在该类的“char”类中实现一个扩展方法,如“GetUnicodeName”。我特意将值限制在0到0xFFFF的范围内。因为这是.NET UTF-16字符所能容纳的全部内容。.NET字符实际上并不表示真正的“字符”(也称为码位),而是Unicode UTF-16代码单元,因为有些“字符”实际上需要两个代码单元。这样的一对代码单元称为高和低代理。大于0xFFFF的值(16位字符可以存储的最大值)在基本多语言平面(BMP)之外,并且根据UTF-16编码需要两个
char
来编码。在此实现中,作为代理对一部分的各个代码将以“非专用高代理”、“专用高代理”和“低代理”等名称结束。rhfm7lfc3#
如果使用Process Monitor查看
charmap.exe
访问的文件,您会看到它打开了一个名为C:\Windows\system32\getuname.dll
的文件,该文件包含其资源中的字符名称(实际上资源本身位于特定于文化的子目录中的.mui文件中)。所以你要做的就是使用
LoadString
API从这个文件中获取名字。我写了一个helper类来做这件事:您可以像这样使用它:
3htmauhk4#
这不是. NET的内置功能。你可以从Charmap.exe中找到,它会在状态栏中显示代码点名称。如果你需要在自己的程序中使用它,你可以将Unicode Character Database编译到你的应用程序中。
db2dz4w85#
我不认为.NET中有任何内置的东西来识别这个...但是有一个Unicode character database。
k5ifujac6#
正如Hans Passant和MichaelBray所说,.NET不提供任何获取字符的Unicode名称的内置功能。
您可以使用统一码字符数据库,该数据库位于http://unicode.org/ucd-今天它包含所有统一码5.2字符的完整信息(附录#44)。
另一种方法是使用Windows中的字符Map表,您可以通过开始\应用程序\附件\系统工具\字符Map表(Win+R =〉charmap)访问该Map表
您还可以使用Unicode转换器工具,这是一个http://unicode.codeplex.com上的开源工具,它还提供了一个用户界面,用于获取信息,并从Unicode UCD使用(附录#44)。此软件的基调是,您可以将此应用程序的EnterpriseAppUnitdll添加到您的应用程序中,并使用提供的API。
此程序集包含一些静态方法,这些方法接受“char”并返回名称、十六进制代码、十进制代码等。
ckx4rj1h7#
您可以使用Windows since Fall Creators Update (Version 1709 Build 16299)附带的
u_charName()
ICU API,它可以处理非BMP Unicode字符(值〉0xFFFF):在我的系统上打印: