奇怪的字符编码

时间:2013-08-06 09:58:37

标签: ruby-on-rails ruby encoding special-characters carrierwave

我在我的params中有一个奇怪的行为,因为utf-8传递但特殊字符管理得不好。 我有2个字符,而不是1个特殊字符:普通字母+重音。

Parameters: {"name"=>"Mylène.png", "_cardbiz_session"=>"be1d5b7a2f27c7c4979ac4c16fe8fc82", "authenticity_token"=>"9vmJ02DjgKYCpoBNUcWwUlpxDXA8ddcoALHXyT6wrnM=", "asset"=>{"file"=># < ActionDispatch::Http::UploadedFile:0x007f94d38d37d0 @original_filename="Mylène.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"asset[file]\"; filename=\"Myle\xCC\x80ne.png\"\r\nContent-Type: image/png\r\n", @tempfile=# < File:/var/folders/q5/yvy_v9bn5wl_s5ccy_35qsmw0000gn/T/RackMultipart20130805-51100-1eh07dp > >}, "id"=>"copie-de-sm"}

我记录下来了:

  • logger.debug file_name
  • logger.debug file_name.chars.map(&amp;:to_s).inspect

每次都有相同的结果:

  • Mylene的
  • [“M”,“y”,“l”,“e”,“”,“n”,“e”]

当我尝试使用文件名作为匹配器,已经存在的名称正确编码为utf-8时,您会看到我的问题;)

  • 编码在任何地方都是utf-8。
  • 在ruby 1.9.3和rails 3.2.14下工作。
  • 在所涉及的任何文件中添加了#encoding:utf-8。

我是一个想法,接受它!

我还在这里发布了一个问题:https://github.com/carrierwaveuploader/carrierwave/issues/1185但不确定它是否存在载波问题或我错过了什么......

2 个答案:

答案 0 :(得分:3)

似乎与MACOSX相关联。

https://www.ruby-forum.com/topic/4407424解释了这一点,并提到https://bugs.ruby-lang.org/issues/7267了解更多细节和讨论。

MACOSX将特殊字符分解为 utf8-mac 而不是 utf-8 ......

虽然您无法知道文件名的编码,但只需预先设定。

感谢我们的Linux人员正常工作。 ;)

file_name.encode!('utf-8', 'utf-8-mac').chars.map(&:to_s)

答案 1 :(得分:1)

也许你有一个 Combining character 并且问题Unicode equivalence

当我用:

检查代码点时
#encoding: utf-8
Parameters =  {"name"=>"Mylène.png",}

p Parameters['name'].codepoints.to_a

我得到Myl\u00E8ne.png,但我认为在复制文本时这是转换问题。如果您可以提供包含原始数据的文件,那将会很有帮助。

我希望您有combining grave accente

解决方案是Unicode规范化。 (对不起,我不知道如何用红宝石做。也许其他人有答案)。


您找到了问题,因此您不再需要这样做了。

但与此同时,我找到了一种规范化Unicode字符串的机制:

#encoding: utf-8
text = "Myl\u00E8ne.png" #"Mylène.png"
text2 = "Myle\u0300ne.png" #"Mylène.png"

puts text   #Mylène.png
puts text2  #Mylène.png

p text == text2 #false

#http://apidock.com/rails/ActiveSupport/Multibyte/Unicode/normalize
require 'active_support'
p text                                                                   #"Myl\u00E8ne.png"
p ActiveSupport::Multibyte::Unicode.normalize(text, :d) #"Myle\u0300ne.png"

p text2                                                                   #"Myle\u0300ne.png"
p ActiveSupport::Multibyte::Unicode.normalize(text2, :c)#"Myl\u00E8ne.png"

也许有一种更简单的方法,但到目前为止我找不到。