.Net中有没有办法找出某个字符有哪些Unicode名称?
如果没有,是否有可以执行此操作的库?
答案 0 :(得分:23)
答案 1 :(得分:10)
这是一个可以立即实施的解决方案,例如复制/粘贴/编译。
首先,在此处下载Unicode数据库(UCD):http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
接下来,将此代码添加到项目中以读取UCD并创建一个Dictionary来查找.NET char值的名称:
string[] unicodedata = File.ReadAllLines( "UnicodeData.txt", Encoding.UTF8 );
Dictionary<char,string> charname_map = new Dictionary<char,string>( 65536 );
for (int i = 0; i < unicodedata.Length; i++)
{
string[] fields = unicodedata[i].Split( ';' );
int char_code = int.Parse( fields[0], NumberStyles.HexNumber );
string char_name = fields[1];
if (char_code >= 0 && char_code <= 0xFFFF) //UTF-16 BMP code points only
{
bool is_range = char_name.EndsWith( ", First>" );
if (is_range) //add all characters within a specified range
{
char_name = char_name.Replace( ", First", String.Empty ); //remove range indicator from name
fields = unicodedata[++i].Split( ';' );
int end_char_code = int.Parse( fields[0], NumberStyles.HexNumber );
if (!fields[1].EndsWith( ", Last>" ))
throw new Exception( "Expected end-of-range indicator." );
for (int code_in_range = char_code; code_in_range <= end_char_code; code_in_range++)
charname_map.Add( (char)code_in_range, char_name );
}
else
charname_map.Add( (char)char_code, char_name );
}
}
UnicodeData.txt文件采用UTF-8编码,由每个Unicode代码点的一行信息组成。每行包含一个以分号分隔的字段列表,其中第一个字段是十六进制的Unicode代码点(没有前缀),第二个字段是字符名称。有关该文件的信息以及每行包含的其他字段可以在此处找到:有关UCD格式的信息,请访问:http://www.unicode.org/reports/tr44/#Format_Conventions
使用上面的代码构建字符到字符名称的映射后,您只需从地图中检索它们,如下所示:
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";
我建议在应用程序资源中嵌入UnicodeData.txt文件,并将此代码包装到一个类中,该类在静态初始化程序中加载和解析文件一次。为了使代码更具可读性,您可以在类'char'类中实现扩展方法,如'GetUnicodeName'。我故意将值限制在0到0xFFFF的范围内,因为这是.NET UTF-16 char所能容纳的。 .NET char实际上并不代表真正的“字符”(也称为代码点),而是Unicode UTF-16代码单元,因为一些“字符”实际上需要两个代码单元。这样的一对代码单元被称为高和低代理。高于0xFFFF(16位字符可以存储的最大值)的值超出基本多语言平面(BMP),并且根据UTF-16编码,需要两个char
来编码。作为代理对的一部分的个人代码最终将使用“非私人使用高代理人”,“私人使用高代理人”和“低代理人”这样的名称。
答案 2 :(得分:8)
如果您使用进程监视器查看charmap.exe
访问的文件,您将看到它打开一个名为C:\Windows\system32\getuname.dll
的文件。此文件包含其资源中的字符名称(实际上资源本身位于特定于区域性的子目录中的.mui文件中)。
所以你要做的就是使用LoadString
API从这个文件中获取名称。我写了一个辅助类来做它:
public class Win32ResourceReader : IDisposable
{
private IntPtr _hModule;
public Win32ResourceReader(string filename)
{
_hModule = LoadLibraryEx(filename, IntPtr.Zero, LoadLibraryFlags.AsDataFile | LoadLibraryFlags.AsImageResource);
if (_hModule == IntPtr.Zero)
throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
}
public string GetString(uint id)
{
var buffer = new StringBuilder(1024);
LoadString(_hModule, id, buffer, buffer.Capacity);
if (Marshal.GetLastWin32Error() != 0)
throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
return buffer.ToString();
}
~Win32ResourceReader()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (_hModule != IntPtr.Zero)
FreeLibrary(_hModule);
_hModule = IntPtr.Zero;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool FreeLibrary(IntPtr hModule);
[Flags]
enum LoadLibraryFlags : uint
{
AsDataFile = 0x00000002,
AsImageResource = 0x00000020
}
}
你可以像这样使用它:
string path = @"C:\Windows\System32\getuname.dll";
using (var reader = new Win32ResourceReader(path))
{
string name = reader.GetString(0xA9);
Console.WriteLine(name); // Copyright Sign
}
答案 3 :(得分:6)
它不是.NET中的内置功能。您可以从Charmap.exe中找到它,它在状态栏中显示代码点名称。如果您在自己的程序中需要,可以将Unicode Character Database编译到您的应用程序中。谨防版权。
答案 4 :(得分:4)
我认为.NET中没有任何内容可以识别这个......但是有一个Unicode character database。
答案 5 :(得分:0)
正如NoBugz和MichaelBray所说.net不提供任何内置功能来获取Unicode字符名称。
你必须使用Unicode字符数据库,它在http://unicode.org/ucd提供bUnicode.o今天它包含所有unicode 5.2 charcaters信息的完整信息(附件#44)
另一种选择是从Windows使用角色地图wicth您可以通过Start \ App Programs \ Accessories \ System Tools \ Character Map(win + R =&gt; charmap)访问它
此外,您可以使用Unicode转换器工具,它是http://unicode.codeplex.com的开源工具,它还提供用于获取信息的用户界面以及从Unicode UCD使用它(附录#44)该软件的主题演讲对于您而言,您可以将此应用程序的 EnterPriseAppUnit dll添加到您的allication中并使用提供的API。
此程序集包含一些静态方法,该方法提供Char并返回Name,HexCode,Decimal Code等