Ruby on rails 为什么Rails 3认为xE2x80x89意味着â;x80 x89

Ruby on rails 为什么Rails 3认为xE2x80x89意味着â;x80 x89,ruby-on-rails,unicode,utf-8,utf-16,multibyte,Ruby On Rails,Unicode,Utf 8,Utf 16,Multibyte,我有一个从utf-8页面上刮取的字段: "O’Reilly" 并保存在yml文件中: :name: "O\xE2\x80\x99Reilly" (xE2x80x99为最新版本) 但是,当我将该值加载到散列中并将其输出到标记为utf-8的页面时,我得到: OâReilly 我查找了字符–在UTF-16中编码为x00E2,当我粘贴字符串时,字符x80和x89不可见,但在–之后出现。我假设这意味着我的应用程序输出三个UTF-16字符,而不是一个UTF-8字符 如何让rails将3字节UTF-8代

我有一个从utf-8页面上刮取的字段:

"O’Reilly"
并保存在yml文件中:

:name: "O\xE2\x80\x99Reilly"
(xE2x80x99为最新版本)

但是,当我将该值加载到散列中并将其输出到标记为utf-8的页面时,我得到:

OâReilly
我查找了字符–在UTF-16中编码为x00E2,当我粘贴字符串时,字符x80和x89不可见,但在–之后出现。我假设这意味着我的应用程序输出三个UTF-16字符,而不是一个UTF-8字符


如何让rails将3字节UTF-8代码解释为单个字符?

Ruby字符串是字节序列而不是字符:

$ irb
>> "O\xE2\x80\x99Reilly"
=> "O\342\200\231Reilly"
您的字符串是一个10字节但8个字符的序列(如您所知)。要确保在HTML中输出正确的字符串,最安全的方法是将不可打印的字符转换为HTML实体(我假设您需要HTML,因为您提到了Rails);就你而言

O’Reilly

这需要一些工作,但在以UTF-8格式发送HTML但最终用户已将其浏览器设置为覆盖并显示Latin-1或其他愚蠢的受限字符集的情况下,这应该会有所帮助。

Ruby字符串是字节序列,而不是字符:

$ irb
>> "O\xE2\x80\x99Reilly"
=> "O\342\200\231Reilly"
您的字符串是一个10字节但8个字符的序列(如您所知)。要确保在HTML中输出正确的字符串,最安全的方法是将不可打印的字符转换为HTML实体(我假设您需要HTML,因为您提到了Rails);就你而言

O’Reilly
这需要一些工作,但在以UTF-8格式发送HTML,但最终用户已将其浏览器设置为覆盖并显示Latin-1或其他愚蠢的受限字符集的情况下,这应该会有所帮助

我假设这意味着我的应用程序输出三个UTF-16字符,而不是一个UTF-8字符

它并不是真正的UTF-16,它很少在网络上使用(并且大部分在网络上中断)。您的应用程序正在输出三个Unicode字符(包括两个不可见的控制代码),但这与UTF-16编码不同

问题似乎是YAML文件正在被读取,就像它是ISO-8859-1编码的一样,因此
\xE2
字节映射到字符U+00E2,以此类推。我猜您使用的是Ruby 1.9,YAML被解析为具有相关ASCII-8BIT编码的字节字符串,而不是UTF-8,这导致字符串在以后经历一轮的段编码(混乱)

如果是这种情况,您可能必须
强制\u编码
将读取的字符串恢复到它们应该的状态,或者设置
默认\u内部
以使字符串读回UTF-8。今天有点乱

我假设这意味着我的应用程序输出三个UTF-16字符,而不是一个UTF-8字符

它并不是真正的UTF-16,它很少在网络上使用(并且大部分在网络上中断)。您的应用程序正在输出三个Unicode字符(包括两个不可见的控制代码),但这与UTF-16编码不同

问题似乎是YAML文件正在被读取,就像它是ISO-8859-1编码的一样,因此
\xE2
字节映射到字符U+00E2,以此类推。我猜您使用的是Ruby 1.9,YAML被解析为具有相关ASCII-8BIT编码的字节字符串,而不是UTF-8,这导致字符串在以后经历一轮的段编码(混乱)


如果是这种情况,您可能必须
强制\u编码
将读取的字符串恢复到它们应该的状态,或者设置
默认\u内部
以使字符串读回UTF-8。这有点乱。

最终,这是由于在rails中用psych加载了一个syck文件(由外部脚本生成)造成的。使用syck加载解决了以下问题:

#in ruby environment
puts YAML::ENGINE.yamler => syck

#in rails
puts YAML::ENGINE.yamler => psych

#in webapp
YAML::ENGINE.yamler = 'syck'
a = YAML::load(file_saved_with_syck)
a[index][:name] => "O’Reilly"
YAML::ENGINE.yamler = 'psych'

最终,这是由于在rails中使用psych加载一个syck文件(由外部脚本生成)造成的。使用syck加载解决了以下问题:

#in ruby environment
puts YAML::ENGINE.yamler => syck

#in rails
puts YAML::ENGINE.yamler => psych

#in webapp
YAML::ENGINE.yamler = 'syck'
a = YAML::load(file_saved_with_syck)
a[index][:name] => "O’Reilly"
YAML::ENGINE.yamler = 'psych'

我会记住这一点,但我需要在数据库中存储utf-8字符串。不用担心,数据库存储utf-8字节序列。Ruby1.9有点帮助。这个链接有用吗?我会记住这一点,但我需要在数据库中存储utf-8字符串。不用担心,数据库存储utf-8字节序列。Ruby1.9有点帮助。这个链接有用吗?啊,我没有意识到xE2也映射到iso-8859-1中的。谢谢。啊,我没有意识到xE2也映射到iso-8859-1中的。谢谢