【问题标题】:Encode while preserving undefined characters在保留未定义字符的同时进行编码
【发布时间】:2016-07-09 19:24:51
【问题描述】:

这里我从外部 db ãƒ\u008F 得到一个字符串,我想将它转换回 unicode 字符。我知道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?"

这是合理的,因为0x8fwindows-1252 的代码页中未定义。

----------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')
# => "ハ"

【问题讨论】:

  • 你指向一个 ?类型字符,通常表示无效。有no such character in Windows-1252,因此将其编码为错误。为什么不使用force_encoding
  • 如果字符串已经具有 UTF-8 表示的正确字节,那么解决方案是(如@tadman 所说),执行str.force_encoding('utf-8')。这就是所有必要的。如果实际字节已经正确,则不应使用 encode
  • @Jordan,问题是,字符串的表示是ãƒ\u008F"ãƒ\u008F".force_encoding('utf-8')仍然是ãƒ\u008F
  • 您从数据库中获取的字符串的实际字节值是多少(十进制或十六进制)?
  • 问题是,字符串的表示是 ãƒ\u008F -- 你说的好像一个字符串只有一个表示。我说字符串的表示是。谁是对的?您的数据库正在使用带有 Windows-1252 镜头的相机来拍摄原始字节的照片。我正在使用带有 UTF-8 镜头的相机来拍摄原始字节的照片。我们的想法是为您的相机选择合适的镜头。 force_encoding() 将允许您选择正确的镜头

标签: ruby encoding utf-8 windows-1252


【解决方案1】:

我想我对这里发生的事情有一个模糊的概念,但我无法做出正确的解释。不过,这是一种至少适用于您的示例的解决方案:

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

当然,这对于大文本来说效率很低,但希望它会有所帮助。如果稍后我有足够的资金,我会回来尝试添加更好的解释。

【讨论】:

  • 我知道你在这里做什么。从windows-1252 获得命令并用它自己的命令进行救援。希望有更好的方法来做到这一点。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-07
  • 1970-01-01
  • 2021-10-31
相关资源
最近更新 更多