Ruby脚本中的Unicode字符?

我想写一个Ruby脚本,它将日文字符写入控制台。 例如:

puts "こんにちは・今日は" 

但是,运行它时会出现exception:

 jap.rb:1: Invalid char `\377' in expression jap.rb:1: Invalid char `\376' in expression 

有可能吗? 我正在使用Ruby 1.8.6。

您已经将文件保存为UTF-16LE编码,一个Windows误导性地称为“Unicode”。 这种编码通常最好避免,因为它不是ASCII超集:每个代码单元存储为两个字节,ASCII字符的另一个字节存储为\0 。 这会混淆很多软件; 使用UTF-16进行文件存储是不常见的。

您所看到的\377\376 (八进制为\xFF\xFE )是放在UTF-16文件前面的U + FEFF字节顺序标记序列,用于区分UTF-16LE和UTF-16BE。

Ruby 1.8完全基于字节; 它不会尝试从脚本中读取Unicode字符。 因此,您只能以ASCII兼容编码保存源文件。 通常,您希望将文件保存为UTF-8(没有BOM; UTF-8虚拟BOM是另一项伟大的Microsoft创新,可以破坏所有内容)。 这对于生成UTF-8页面的Web上的脚本非常有用。

如果您想确保源代码能够容忍以任何与ASCII兼容的编码保存,您可以对字符串进行编码以使其更具弹性(如果不太可读):

 puts "\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf\xe3\x83\xbb\xe4\xbb\x8a\xe6\x97\xa5\xe3\x81\xaf" 

然而! 写入控制台本身就是一个大问题。 使用什么编码将字符发送到控制台因平台而异。 在Linux或OS X上,它是UTF-8。 在Windows上,它是每个安装区域设置的不同编码(在“区域和语言选项”控制面板条目中的“非Unicode应用程序的语言”中选择),但它从不是 UTF-8。 此设置再次被误导地称为ANSI代码页。

因此,如果您使用的是日语Windows安装,则您的控制台编码将是Windows代码页932(Shift-JIS的变体)。 如果是这种情况,您可以使用“ANSI”或显式“日语cp932”从文本编辑器中保存文本文件,当您在Ruby中运行它时,您将获得正确的字符。 同样,如果你想让源代码能够承受错误编码,你可以在cp932编码中转义字符串:

 puts "\x82\xb1\x82\xf1\x82\xc9\x82\xbf\x82\xcd\x81E\x8d\xa1\x93\xfa\x82\xcd" 

但是如果你在另一个语言环境中的机器上运行它,它将产生不同的字符。 在Western Windows安装中,您将无法从Ruby将日语写入默认控制台(代码页1252)。

(虽然Ruby 1.9大大改进了Unicode处理,但它在这里没有任何改变。它仍然是一个使用C标准库IO函数的基于字节的应用程序,这意味着它仅限于Windows的本地代码页。)