如何使用Ruby 1.9转换字符编码

w1jd8yoj  于 2023-03-01  发布在  Ruby
关注(0)|答案(2)|浏览(137)

我目前在处理Amazon API的结果时遇到了问题。
服务返回一个包含Unicode字符的字符串:* 在Mac上学习目标\xE2\x80\x93C(学习系列)*
在Ruby 1.9.1中,这个字符串甚至不能被处理:

REXML::ParseException: #<Encoding::CompatibilityError: incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)>

...

Exception parsing

Line: 1

Position: 1636

Last 80 unconsumed characters:

Learn Objective–C on the Mac (Learn Series)
ql3eal8s

ql3eal8s1#

例外的是,你的字符串是ASCII-8BIT编码的,你应该改变编码,有一个long story,但是如果你想快速解决问题,在你做任何处理之前,只需要对字符串进行force_encoding

s = "Learn Objective\xE2\x80\x93C on the Mac"
# => "Learn Objective\xE2\x80\x93C on the Mac"
s.encoding
# => #<Encoding:ASCII-8BIT>
s.force_encoding 'utf-8'
# => "Learn Objective–C on the Mac"
1dkrff03

1dkrff032#

如果所有以ASCII-8BIT编码的字符都可以直接转换为UTF-8,那么Mladen的解决方案就有效了。当存在1)无效字符或2)UTF-8中未定义的字符时,它就会中断。但是,这是有效的(在1.9.2及更高版本中:

new_str = s.encode('utf-8', 'binary', :invalid => :replace, 
  :undef => :replace, :replace => '')

ASCII-8BIT实际上是二进制的。这段代码将编码转换为UTF-8,同时正确地处理无效和未定义的字符。:invalid选项指定要替换无效字符。:undef选项指定要替换未定义字符。:replace选项定义无效或未定义字符应该替换为什么。在本例中,我选择简单地删除它们。

相关问题