Вот решение, которое вы можете реализовать немедленно, например, копировать / вставить / скомпилировать.
Сначала загрузите базу данных Unicode (UCD) здесь: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt
Затем добавьте этот код в ваш проект, чтобы прочитать UCD, и создайте словарь для поиска имени значения символа .NET:
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. .NET char на самом деле не представляет собой настоящий «символ» (также называемый кодовой точкой), а представляет собой кодовую единицу Unicode UTF-16, поскольку для некоторых «символов» фактически требуются две кодовые единицы. Такая пара кодовых единиц называется суррогатом высокого и низкого уровня. Значения выше 0xFFFF (наибольшее значение, которое может хранить 16-битный символ) находятся за пределами базовой многоязычной плоскости (BMP), и согласно кодированию UTF-16 для кодирования требуется два char
с. Индивидуальные коды, которые являются частью суррогатной пары, будут иметь такие имена, как «Высокий суррогат не частного использования», «Высокий суррогат частного использования» и «Низкий суррогат» в этой реализации.