UTF-8转换不使用String#encode但是Iconv

Dra*_*aco 3 ruby ruby-on-rails

我和Iconv有这个:

git_log = Iconv.conv 'UTF-8', 'iso8859-1', git_log
Run Code Online (Sandbox Code Playgroud)

现在我想将其更改为使用String #catit,因为弃用警告,但我不能,不起作用:

git_log = git_log.encode(Encoding::UTF_8, :invalid => :replace, :undef => :replace, :replace => '')
Run Code Online (Sandbox Code Playgroud)

我以前在这里使用Iconv,它仍在工作:

https://github.com/gamersmafia/gamersmafia/blob/master/lib/formatting.rb#L244

但是当我用String #coding方法替换这些行时,首先gsub引发"UTF-8中的无效字节序列"错误.

你知道为什么吗?

mat*_*att 6

在您的通话中,String#encode请勿指定源编码.Ruby使用字符串当前编码作为源,看起来是UTF-8,并根据文档:

请注意,从编码enc到相同编码的转换enc是无操作,即接收器在没有任何更改的情况下返回,并且即使存在无效字节也不会引发异常.

换句话说,调用没有效果,并将字符串保留在字符串中,编码为ISO-8859-1.然后下一次调用gsub尝试将这些字节解释为UTF-8,并且由于它们无效(它们与ISO-8859-1相同),您将看到错误.

String#encode有一个接受源编码作为第二个参数的表单,因此您可以显式指定它,类似于您使用Iconv执行的操作.试试这个:

git_log = git_log.encode(Encoding::UTF_8,
                         Encoding::ISO_8859_1,
                         :invalid => :replace,
                         :undef => :replace,
                         :replace => '')
Run Code Online (Sandbox Code Playgroud)

您也可以!在这种情况下使用表单,它具有相同的效果:

git_log.encode!(Encoding::UTF_8,
                Encoding::ISO_8859_1,
                :invalid => :replace,
                :undef => :replace,
                :replace => '')
Run Code Online (Sandbox Code Playgroud)