有效地使用 UTF-8 编码字符串
Effectively UTF-8 encode a string
我是 运行 WSL Debian 上的一个脚本,它从本地安装的共享驱动器中获取 Windows 文件。问题是文件名编码错误,即使 #encoding
returns #<Encoding:UTF-8>
。示例:
"J\u00E9r\u00E9my".encoding # #<Encoding:UTF-8>
\u00E9
是é
的Unicode字符,所以我假设编码是Unicode
我已经从相关问题 (Convert a unicode string to characters in Ruby?, How to convert a string to UTF8 in Ruby) 中尝试了几种编码组合,但 none 符合我的需要。
我也尝试过不同的“魔术评论”encoding: <ENCODING>
,但没有令人满意的结果。
您使用什么方法来识别和修复编码问题?
Edit1:Stefan 要求代码点:
"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 应该可以解决问题。
我是 运行 WSL Debian 上的一个脚本,它从本地安装的共享驱动器中获取 Windows 文件。问题是文件名编码错误,即使 #encoding
returns #<Encoding:UTF-8>
。示例:
"J\u00E9r\u00E9my".encoding # #<Encoding:UTF-8>
\u00E9
是é
的Unicode字符,所以我假设编码是Unicode
我已经从相关问题 (Convert a unicode string to characters in Ruby?, How to convert a string to UTF8 in Ruby) 中尝试了几种编码组合,但 none 符合我的需要。
我也尝试过不同的“魔术评论”encoding: <ENCODING>
,但没有令人满意的结果。
您使用什么方法来识别和修复编码问题?
Edit1:Stefan 要求代码点:
"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 应该可以解决问题。