我想编写一个将日文字符写入控制台的Ruby脚本。例如:
puts "こんにちは・今日は"
但是,运行它时会出现异常:
jap.rb:1: Invalid char `\377' in expression
jap.rb:1: Invalid char `\376' in expression
有可能吗?我正在使用Ruby 1.8.6。
答案 0 :(得分:12)
您已将文件保存为UTF-16LE编码,一个Windows误导性地称为“Unicode”。通常最好避免使用此编码,因为它不是ASCII超集:每个代码单元存储为两个字节,ASCII字符的另一个字节存储为\0
。这会混淆很多软件;使用UTF-16进行文件存储是不常见的。
您在\377
和\376
(\xFF
和\xFE
的八进制)中看到的是U + FEFF字节顺序标记序列放在UTF的前面用于区分UTF-16LE和UTF-16BE的16个文件。
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安装(代码页1252)上,您将无法从Ruby将日语写入默认控制台。
(虽然Ruby 1.9大大改进了Unicode处理,但它在这里没有任何改变。它仍然是使用C标准库IO函数的基于字节的应用程序,这意味着它仅限于Windows的本地代码页。)< / p>