Ruby 文件编码转换与中文路径的那些事儿

john1king · 2011年11月20日 · 最后由 wxianfeng 回复于 2012年02月04日 · 10108 次阅读

学习 ruby 有两个月,这门语言确实不错,让我思路开拓不少。只是在目前国内用的人太少,碰到很多小问题都得上外网站找,但编码问题困扰了我很久,一直没找到什么好的解决办法。编码问题应该是很常见的任务了,所以想知道大家的解决方案。下面也给出了我写的代码,希望能够抛砖引玉。还有很多不懂的地方,请多多指教

我想要程序能够自动判断文件的编码(主要是 shift-jis , gbk 和 utf-8 with bom 这几种),然后统一转换为 utf-8 无 bom 格式

String 类虽然有 force_encoding 和 valid_encoding?方法,但准确性很低,所以 现在的做法是尝试转换每一种编码,直到成功为止再进行处理。就目前用过的几次来看,成功率还不算太低,所以就没用 iconv 了。代码在最下面,也可看这里 https://gist.github.com/1380350

另外还有两个小问题

  1. ruby 里除了 open 方法外,大多文件操作时候都不会帮你处理好系统编码的问题。每次都是先转成 gbk 再转 转回来。不知道有没有现成的 gem 解决这个问题

  2. 似乎传递给 Dir.glob 的路径里包含“[”和”]”就找不到路径了,这是 bug 吗?我现在只能用?代替这两个字符

# 运行环境 win7, ruby 1.9.2 p290

def txt_to_utf(file)
    open(file) do |f|
        s = f.read
        #shift_jis 必须写在前面,因为被误判为gbk的概率很高
        x = %w(shift_jis gbk big5)

        begin
        u = s.dup.encode("utf-8",x.shift)
        rescue Encoding::UndefinedConversionError,Encoding::InvalidByteSequenceError => ex

            if x.empty? 

                if s.chr.ord.to_s(16) == "efbb"
                    #处理utf-8 with bom 文件
                end

            else
                retry
            end
        else

        #处理 shift-jis, gbk, big5 文件

        end
    end
end

检测编码有没有试过 rchardet? https://github.com/jmhodges/rchardet/

require 'rubygems'
require 'rchardet'

cd = CharDet.detect(some_data)
encoding = cd['encoding']
confidence = cd['confidence'] # 0.0 <= confidence <= 1.0

Python 有个 chardet http://pypi.python.org/pypi/chardet

  1. 别用中文路径(怎么可能用中文路径呢!?)
  2. 别在 Windows 下面搞(这事儿我反复说过很多次了)
  3. 文件存档都用 UTF-8 编码

@zhangyuan 我试过 chardet,但不支持 1.9。原来还有个 rchardet,看起来要新很多,回家再试试

@huacnlee 1.你可能误解了我的意思。这个主要是为了解决日常遇到的小问题和学习,不是开发 2.打算入手 macbook,正在缩衣简食 3.一些是网上下的

#3 楼 @john1king 其实也不一定买 Mac 啊,可以用 Linux,反正不要在 Windows 上面搞,这样你会话很多时间去调一些完全没有必要的问题

在 Github 上搜 chardet,有好几个呢

https://github.com/janx/chardet This is a ruby 1.9 compatible version of chardet on http://rubyforge.org/projects/chardet/

#5 楼 @zhangyuan 你找没有 forked from 的一般就是原始代码库~ '正版'的~

几个当中就https://github.com/kirillrdy/rchardet 支持 1.9 不过日文编码时还是有错误 http://rubyforge.org/tracker/index.php?func=detail&aid=22658&group_id=3327&atid=12770

所以我也 fork 了一个,https://github.com/JohnKing/rchardet

准确率还是蛮高的

松本行弘的程序世界 一书对 编码讲的很透彻

需要 登录 后方可回复, 如果你还没有账号请 注册新账号