2016-03-22 5 views
-1

Здесь я получил строку извне db ãƒ\u008F, и я хочу преобразовать ее обратно в символ Юникода. Я знаю, что db использует кодировку windows-1252, поэтому фактический символ должен быть \xe3\x83\x8f, который является в кодировке utf-8.Кодировать при сохранении неопределенных символов

Вот то, что я пытался до сих пор

"ãƒ\u008F".encode('windows-1252') 
# => Encoding::UndefinedConversionError: U+008F to WINDOWS-1252 in conversion from UTF-8 to WINDOWS-1252 

"ãƒ\u008F".encode('windows-1252', undef: :replace) 
# => "\xE3\x83?" 

Это разумно, поскольку 0x8f не определено в кодировке windows-1252 «s.

----------Windows-1252----------- 
    0 1 2 3 4 5 6 7 8 9 a b c d e f 
2 ! " # $ % & ' () * + , - ./
3 0 1 2 3 4 5 6 7 8 9 : ; <=> ? 
4 @ A B C D E F G H I J K L M N O 
5 P Q R S T U V W X Y Z [ \ ]^_ 
6 ` a b c d e f g h i j k l m n o 
7 p q r s t u v w x y z { | } ~ 
8 € � ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ � Ž � <---right here! 
9 � ‘ ’ “ ” • – — ˜ ™ š › œ � ž Ÿ 
a   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ 
b ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ 
c À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï 
d Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß 
e à á â ã ä å æ ç è é ê ë ì í î ï 
f ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ 

Вопрос, как я могу кодировать, сохраняя неопределенный символ? А именно, как я могу получить

s = "ãƒ\u008F".some_magic_methods 
# => "\xE3\x83\x8F" 

s.force_encoding('utf-8') 
# => "ハ" 
+0

Вы указываете на? типа, который обычно означает недопустимый. В Windows-1252 нет такого символа (https://en.wikipedia.org/wiki/Windows-1252), поэтому его кодирование является ошибкой. Почему бы не использовать 'force_encoding'? – tadman

+0

Если строка имеет правильные байты для представления UTF-8, то решение (как говорит @tadman), делает 'str.force_encoding ('utf-8')'. Это все, что нужно. Вы не должны использовать 'encode', если фактические байты уже правильны. –

+0

@Jordan, проблема в том, что представление строки является 'ム\ u008F',' "ム\ u008F" .force_encoding ('utf-8') 'все еще' ム\ u008F' – sbs

ответ

1

Я думаю, что у меня есть смутное представление о том, что происходит здесь, но у меня возникают проблемы, формулирующая правильное объяснение. Тем не менее, вот решение, которое, по крайней мере работает для одного примера:

str = "ãƒ\u008F" 
str2 = str.chars.map {|c| c.encode('windows-1252').ord rescue c.ord } 
     .pack('C*').force_encoding('utf-8') 
puts str2 
# => ハ 

Конечно, это очень неэффективно для больших текстов, но, надеюсь, это поможет. Если позже у меня получится, я вернусь и попытаюсь добавить лучшее объяснение.

+0

Я получаю то, что вы здесь делаете. Чтобы получить орд от 'windows-1252' и спасти его собственным ордом. Надеюсь, есть лучший способ сделать это. – sbs