我正在WSL Debian上运行一个脚本,该脚本从本地安装的共享驱动器中获取Windows文件。问题是文件名编码错误,即使#encoding
return #<Encoding:UTF-8>
。例子:
"J\u00E9r\u00E9my".encoding # #<Encoding:UTF-8>
\u00E9
是的Unicode字符é
,因此我假设编码为Unicode
我想从相关问题的几个编码组合(unicode字符串转换为字符在Ruby中?,如何将字符串转换为Ruby的UTF8),但没有一个适合我的需要的。我也尝试了不同的“魔术评论” encoding: <ENCODING>
,但结果却不令人满意。
你识别和解决编码问题的方法是什么?
"J\u00E9r\u00E9my".each_codepoint.to_a
# [74, 233, 114, 233, 109, 121]
和 Encoding.default_external
Encoding.default_external
# #<Encoding:US_ASCII>
令我惊讶的是,我# encoding: utf-8
在文件顶部添加了神奇的注释
Edit2:显式设置default_internal
和default_external
编码以Encoding::UTF_8
解决问题
# encoding: utf-8
Encoding.default_internal = Encoding::UTF_8
Encoding.default_external = Encoding::UTF_8
尽管我想走得更远,并真正理解为什么需要这样做
"J\u00E9r\u00E9my".encoding #=> #<Encoding:UTF-8> "J\u00E9r\u00E9my".each_codepoint.to_a #=> [74, 233, 114, 233, 109, 121]
琴弦非常好。它们包含正确的字节并具有正确的编码。
由于你的外部编码设置为(或识别为)US-ASCII,因此以这种方式打印它们:
Encoding.default_external #=> #<Encoding:US_ASCII>
Ruby假定你的终端只能渲染ASCII字符,因此使用转义序列打印UTF-8字符。(使用p
/时String#inspect
)
外部编码通常是根据你的语言环境自动确定的:
$ LANG=C ruby -e 'p Encoding.default_external'
#<Encoding:US-ASCII>
$ LANG=en_US.UTF-8 ruby -e 'p Encoding.default_external'
#<Encoding:UTF-8>
将终端或系统的编码/语言环境设置为UTF-8应该可以解决此问题。
对于未来的访问者:请注意,String#codepoints是的简写
str.each_codepoint.to_a
。两种方法的结果都是相同的。确实,它来自我的终端设置。尽管WSL的终端说它正在使用UTF-8,但从另一个终端运行脚本会正确打印加重的字符。我将研究WSL设置,感谢您引导我朝着正确的方向发展!