代码之家  ›  专栏  ›  技术社区  ›  Ethan

如何在Ruby中将字符串从windows-1252转换为utf-8?

  •  9
  • Ethan  · 技术社区  · 15 年前

    我正在使用Windows XP上的Ruby 1.8.6将一些数据从MS Access 2003迁移到MySQL 5.0(为此编写一个Rake任务)。

    事实证明,Windows字符串数据编码为Windows-1252,Rails和MySQL都采用utf-8输入,因此一些字符(如撇号)被损坏。他们最后被称为“a”,带着口音等等。

    有人知道将windows-1252字符串转换为utf-8的工具、库、系统、方法、仪式、拼写或咒语吗?

    5 回复  |  直到 15 年前
        1
  •  10
  •   austinfromboston    15 年前

    对于Ruby 1.8.6,您似乎可以使用Ruby Iconv,它是标准库的一部分:

    Iconv documentation

    据此 helpful article ,看起来您至少可以从字符串中清除不需要的win-1252字符,如下所示:

    ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
    valid_string = ic.iconv(untrusted_string + ' ')[0..-2]
    

    ic = Iconv.new('UTF-8', 'WINDOWS-1252')
    valid_string = ic.iconv(untrusted_string + ' ')[0..-2]
    
        2
  •  9
  •   James A. Rosen    15 年前

    如果您使用的是Ruby 1.9。。。

    string_in_windows_1252 = database.get(...)
    # => "FÃ¥bulous"
    
    string_in_windows_1252.encoding
    # => "windows-1252"
    
    string_in_utf_8 = string_in_windows_1252.encode('UTF-8')
    # => "Fabulous"
    
    string_in_utf_8.encoding
    # => 'UTF-8'
    
        3
  •  3
  •   Overbryd    15 年前

    Hy,

    我也有同样的问题。

    以下提示帮助我成功:

    始终检查正确的编码名称,以便正确输入转换工具。 如有疑问,您可以通过以下方式获得iconv或recode支持的编码列表:

    $ recode -l
    

    $ iconv -l
    

    始终从原始文件开始,对要使用的样本进行编码:

    $ recode windows-1252..u8 < original.txt > sample_utf8.txt
    

    $ iconv -f windows-1252 -t utf8 original.txt -o sample_utf8.txt
    

    这篇文章帮助很大: http://blog.nuclearsquid.com/writings/ruby-1-9-encodings

    File.open('original.txt', 'r:windows-1252:utf-8')
    # This opens a file specifying all encoding options. r:windows-1252 means read it as windows-1252. :utf-8 means treat it as utf-8 internally.
    

    玩得开心,说很多脏话!

        4
  •  2
  •   yhager    15 年前

    $ iconv -f windows-1252 -t utf-8 win1252_file > utf8_file
    

    使用cygwin在Windows上可能也可以这样做。

        5
  •  2
  •   Community PPrice    7 年前

    如果你是 在Ruby 1.9上,假设 yhager

    File.open('/tmp/w1252', 'w') do |file|
      my_windows_1252_string.each_byte do |byte|
        file << byte
      end
    end
    
    `iconv -f windows-1252 -t utf-8 /tmp/w1252 > /tmp/utf8`
    
    my_utf_8_string = File.read('/tmp/utf8')
    
    ['/tmp/w1252', '/tmp/utf8'].each do |path|
      FileUtils.rm path
    end