加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 如何在导入YAML文件时使用内部/外部编码?

发布时间:2020-12-17 03:32:51 所属栏目:百科 来源:网络整理
导读:如何加载YAML文件而不管其编码? 我的YAML文件可以用UTF-8或ANSI编码(这就是Notepad所说的 – 我猜它是Windows-1252): :key1: :key2: "?" utf8.yml以UTF-8编码,ansi.yml以ANSI编码.我加载文件如下: # encoding: utf-8Encoding.default_internal = "utf-8"u
如何加载YAML文件而不管其编码?

我的YAML文件可以用UTF-8或ANSI编码(这就是Notepad所说的 – 我猜它是Windows-1252):

:key1:
  :key2: "?"

utf8.yml以UTF-8编码,ansi.yml以ANSI编码.我加载文件如下:

# encoding: utf-8

Encoding.default_internal = "utf-8"

utf8_load      = YAML::load(File.open('utf8.yml'))
utf8_load_file = YAML::load_file('utf8.yml')
ansi_load      = YAML::load(File.open('ansi.yml'))
ansi_load_file = YAML::load_file('ansi.yml')

Ruby似乎无法正确识别编码:

utf8_load      [:key1][:key2].encoding  #=> "UTF-8"
utf8_load_file [:key1][:key2].encoding  #=> "UTF-8"
ansi_load      [:key1][:key2].encoding  #=> "UTF-8"
ansi_load_file [:key1][:key2].encoding  #=> "UTF-8"

因为字节不一样:

utf8_load      [:key1][:key2].bytes  #=> [195,164]
utf8_load_file [:key1][:key2].bytes  #=> [195,164]
ansi_load      [:key1][:key2].bytes  #=> [239,191,189]
ansi_load_file [:key1][:key2].bytes  #=> [239,189]

如果我错过了Encoding.default_internal =“utf-8”,字节也不同:

utf8_load      [:key1][:key2].bytes  #=> [195,131,194,164]
ansi_load      [:key1][:key2].bytes  #=> [195,164]
ansi_load_file [:key1][:key2].bytes  #=> [239,189]

>当我没有将default_internal设置为utf-8时会发生什么?
>两个例子中的字符串都有哪些编码?
>即使我不知道它的编码,我如何加载文件?

解决方法

我相信YAML官方只支持UTF-8(也许是UTF-16).历史上,YAML库中存在各种编码混淆.我认为你会遇到麻烦试图让YAML不是Unicode编码.

  1. What happens actually when I don’t set the default_internal to utf-8?

Encoding.default_internal控制输入在读入时将被转换为的编码,至少是一些尊重Encoding.default_internal的操作,而不是一切. Rails似乎将其设置为UTF-8.因此,如果您未将Encoding.default_internal设置为UTF-8,则无论如何都可能是UTF-8.

如果Encoding.default_internal为nil,那么那些尊重它的操作,并尝试在读取它时将任何输入转换为Encoding.default_internal将不会这样做,它们将在编码中留下任何输入,它被认为是源自,不要试图转换它.

如果你把它设置为别的东西,比如说“WINDOWS-1252”,当你用File.open读取它时,Ruby会自动将你的东西转换成WINDOWS-1252,当你传递现在的字符串时,这可能会混淆YAML :: load编码并标记为WINDOWS-1252.通常没有充分的理由这样做,所以请单独留下Encoding.default_internal.

注意:Ruby docs说:

“You should not set ::default_internal in Ruby code as strings created before changing the value may have a different encoding from strings created after the change. Instead you should use ruby -E to invoke Ruby with the correct default_internal.”

另见:http://ruby-doc.org/core-1.9.3/Encoding.html#method-c-default_internal

  1. Which encodings do the strings in both examples have?

我真的不知道.人们必须要查看字节并尝试确定它们是否是各种合理编码的合法字节,并且除了合法之外,如果它们意味着可能有意图的话.

例如:“éGéìéR?[éféBéìéO??ì??μ?≠???¢”.这是一个完全合法的UTF-8字符串,但作为人类,我们知道它可能不是预期的,并且可能是垃圾,很可能是由于编码误解的结果.但是计算机无法知道这一点,它是完全合法的UTF-8,而且,嘿,也许有人真的有意义写“éGéìéR?[éféBéìéO??ì??μ?≠???¢”,毕竟我刚才写的这篇文章!

因此,您可以尝试根据各种编码解释字节,看看它们是否有意义.

你真的只是猜测这一点.意思是…

  1. How can I load a file even if I don’t know it’s encoding?

一般来说,你不能.您需要了解并跟踪编码.在不知道编码的情况下,没有真正的方法可以知道字节的含义.

如果您有一些丢失了这些遗留数据,那么您必须尝试解决这个问题.手动或使用一些代码尝试根据启发式猜测可能的编码.这是一个试图猜测的Ruby gem Charlock Holmes,使用ICU库启发式(这个特殊的gem仅适用于MRI).

Ruby在回复string.encoding时所说的只是字符串被标记的编码.字符串可以使用错误的编码进行标记,字符串中的字节实际上并不意味着它标记的编码中的意图…在这种情况下,您将获得垃圾.

Ruby将使用您的字符串执行正确的操作,而不是仅在字符串的编码标记正确时才创建垃圾.对于大多数输入操作,字符串的编码标签由Encoding.default_external确定(Encoding.default_external通常以UTF-8或ASCII-8BIT开头,实际上是空编码,二进制数据,未用编码标记),或者通过将参数传递给File.open:File.open(“something”,“r:UTF-8”或者,意思相同,File.open(“something”,“r”,:encoding =>“UTF) -8“).实际的字节由文件中的任何内容决定.由你来告诉Ruby正确的编码将这些字节解释为文本意味着它们的意思.

最近有一些帖子发送到reddit / r / ruby??,试图解释如何排除故障并解决您可能会发现有用的编码问题:

> http://www.justinweiss.com/articles/how-to-get-from-theyre-to-theyre/
> http://www.justinweiss.com/articles/3-steps-to-fix-encoding-problems-in-ruby/

另外,这是我最喜欢的关于编码的文章:http://kunststube.net/encoding/

特别是对于YAML文件,如果我是你,我只是确保它们都是UTF-8.生活会更容易,你不必担心它.如果你有一些已经损坏的遗留物,修复它们会很痛苦,但这就是你必须要做的事情,除非你可以从头开始重写它们.尝试将它们修复为有效且正确的UTF-8,并从此处开始将所有YAML保存为UTF-8.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读