Ruby脚本中的Unicode字符?

8
我想编写一个Ruby脚本,可以在控制台上输出日语字符。例如:
puts "こんにちは・今日は"

然而,当我运行它时,出现了一个异常:
jap.rb:1: Invalid char `\377' in expression
jap.rb:1: Invalid char `\376' in expression

这可行吗?我正在使用Ruby 1.8.6。

1个回答

12
你已经将文件保存为UTF-16LE编码,这是Windows误称为“Unicode”的一种编码。这种编码通常最好避免使用,因为它不是ASCII的超集:每个代码单元都存储为两个字节,其中ASCII字符的另一个字节存储为\0。这会混淆很多软件;在文件存储中使用UTF-16是不寻常的。
你在使用\377\376(八进制表示的\xFF\xFE)时看到的是U+FEFF字节顺序标记序列,放置在UTF-16文件的前面,以区分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”或明确使用“Japanese cp932”从文本编辑器中保存文本文件,当您在Ruby中运行它时,您将得到正确的字符输出。同样,如果您想使源代码能够抵御误编码,您可以以cp932编码转义字符串:

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

但如果你在另一种语言环境的机器上运行它,它会生成不同的字符。在西方Windows安装(代码页1252)上,你将无法从Ruby向默认控制台写入日文。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接