Как получить наилучшее соответствие отображений символов Юникода между кодировками - PullRequest
4 голосов
/ 23 июня 2011

У меня есть строка UTF-16, которая содержит некоторые символы, которые не представлены непосредственно в моей локальной Windows-1252 кодовой странице:

6/23/2011 9:23:44 ᴀᴍ

я использую WideCharToMultiByte для преобразования строки в локальную кодовую страницу (Windows-1252 на моем североамериканском компьютере):

WideCharToMultiByte(
    CP_ACP, //target CodePage
    0,      //flags
    Source, //my string, e.g. "6/23/2011 9:23:44 ᴀᴍ"
    length, //length in characters, e.g. 20
    buffer, //destination where to put the string
    bufferSize, 
    null,   //optional, character to use when character cannot be represented
    null);  //optional, out boolean that indicates if any character could not be represented

И строка выглядит так:

6/23/2011 9:23:44 ??

Буквально с вопросительными знаками 0x3f = "?" для непредставимых символов.

Когда вы смотрите на символы в исходной строке «ᴀᴍ», два символа:

  • U + 1D00: маленькая буква латинского алфавита A
  • U + 1D0D: латинская буква маленькая заглавная M

Стандарт Unicode гласит: это фонетические расширения, а для общего текста: используйте обычную латиницу . Что для меня означает, что текст должен быть преобразован в:

6/23/2011 9:23:44 AM

или

6/23/2011 9:23:44 am

Другим примером может быть 6′2″:

  • U + 2032: премьер
  • U + 2033: двойной прайм

Когда я преобразую эту строку в Windows-1252, она становится 6'2? (апостроф, ?).

Запись Unicode для Prime перечисляет апостроф в качестве альтернативы:

2032   ′   PRIME
           = minutes, feet
           → 0027 ' apostrophe
           → 00B4 ´ acute accent
           → 02B9 ʹ modifier letter prime

Даже если простое не существует в целевой кодовой странице, WideChartoMultiByte равно , преобразовывая его в один из ближайших эквивалентов (то есть апостроф).

С другой стороны Double Prime :

2033   ″   DOUBLE PRIME
           = seconds, inches
           → 0022 " quotation mark
           → 02BA ʺ modifier letter double prime
           → 201D ” right double quotation mark
           ≈ 2032 ′ 2032 ′

сопоставляется с ничем (?), однако некоторые другие элементы существуют в моей кодировке Windows-1252:

Character                                 Unicode  Windows-1252
========================================= =======  ============
″ double prime                            U+2032      -
" quotation mark                          U+0022     0x22
ʺ modifier letter double prime            U+02BA      -
” right double quotation mark             U+201D     0x94

′ prime                                   U+2032      -
' apostrophe                              U+0027     0x27
´ acute accent                            U+00B4     0xb4
ʹ modifier letter prime                   U+02B9

Даже в худшем случае, когда он разлагает оригинал double prime на prime prime: простое число имеет эквивалент - поскольку он уже использовал его.

Для других персонажей также есть сопоставления:

Character                                 Unicode  Windows-1252
========================================= =======  ============
ᴀ Latin Letter Small Capital A            U+1D00      -
A Latin Capital Letter A                  U+0041     0x41
a Latin Small Letter A                    U+0061     0x61

ᴍ Latin Letter Small Capital M            U+1D0D      -
M Latin Capital Letter M                  U+004D     0x4d
m Latin Small Letter M                    U+006D     0x6d

Как мне сделать, чтобы WideChartoMultiByte наилучшим образом соответствовал отображению между кодировками?

Ответы [ 3 ]

1 голос
/ 24 июня 2011

Насколько хорошо WideCharToMultiByte может зависеть от используемой версии Windows. Я считаю, что более новые версии используют более полные таблицы. Тем не менее, он, вероятно, никогда не охватит все случаи. Поскольку Windows предпочитает Unicode изначально, у них нет особого стимула для реализации всех альтернативных вариантов для миллиардов кодовых страниц.

Вы можете использовать библиотеку (например, ICU, как уже упоминали другие) или создать свой собственный препроцессор для обработки аварийного режима.

1 голос
/ 24 июня 2011

Если вы знаете целевую кодировку, вы можете использовать стандартизированную Posix библиотеку iconv (которая также доступна для Windows) и конвертировать из WCHAR_T или UTF-16 в целевую кодировку;У iconv есть опция «транслитерации», которая может превратить все ваши специальные символы в их транслитерации ASCII.Iconv немного легче, чем ICU, и довольно широко доступен.

1 голос
/ 23 июня 2011

Я не думаю, что вы можете изменить результаты WideCharToMultiByte(). Если вам не терпится попробовать другое решение, ICU может дать вам другие результаты.

Лично я не пробовал, поэтому я не могу гарантировать результаты (кому все равно нужно конвертировать из Unicode?), Но я считаю, что вы должны использовать ICU Converters . Приятно то, что он поддерживает Unicode 6.0 (в любом случае это вам, вероятно, не нужно).

...