Ruby 关于字符串的 split 问题

413472212 · 2012年02月15日 · 最后由 leslin123 回复于 2014年04月15日 · 15130 次阅读

我刚学 ruby,最近遇到个问题不懂,想请教下各位: 有一个 UTF-8 编码的 txt 文件,读取文件的每一行并通过 split 函数将分割,但显示错误: in 'split':invalid byte sequence in GBK(argumenterror)

PS:已经将 ruby 对字符串的编码方式设为 GBK

信息太少,请贴出足够的代码

你要 ruby 处理 GBK 编码的字符串,却喂给它 UTF-8,它会觉得你在坑它。

我认为是这样:

  1. 用 utf-8 读进来並 split
  2. 用 iconv 转为 GBK

#2 楼 @chitsaou 赞同

就像处理时间换算这样的场景,统一将时间先转换程 utc,然后在进行换算。同理,处理任何文本文件之前,现将文件的字符编码转成 utf-8,然后这个世界一下子变得美好了一点点。

但从文件中读取到的字符串利用 encoding 函数显示字符串是 GBK 编码的

#2 楼 @chitsaou 但从文件中读取到的字符串利用 encoding 函数显示字符串是 GBK 编码的

#5 楼 @413472212 因为你用 gbk 去读呀,就像你跟一个美国人说汉语,他会当你在说英语,但其实他不能理解你说了啥 (invalid byte sequence)

#1 楼 @zhangyuan 简化代码如下:

a.each do |line| 
    line.split(' ').each do |word|
        #do something   
    end
end

#3 楼 @lgn21st 麻烦能再具体点吗?刚学 ruby,很多还不是很懂

#1 楼 @zhangyuan

#encoding: GBK
a = File.open("word.txt") #通过另存为知道文件是UTF-8编码
a.each do |line| 
  line.split(' ').each do |word|
    #do something
  end
end

#8 楼 @413472212 简单地说,就是首先将要处理的文本文件的字符编码转换成 UTF-8,然后再用 ruby 去读取并 split 操作。

转换的方法有很多,可以通过 ruby 的库,也可以直接用命令行工具,比如 iconv

$ iconv -f GBK -t UTF-8 input.txt > output.txt

#10 楼 @lgn21st 可以直接用 ruby1.9 的外部编码功能

1.9.2p290 :001 > File.new('file.txt').readlines
 => ["\xC4\xE3\xBA\xC3\n"] 
1.9.2p290 :002 > File.new('file.txt').tap{|f| f.set_encoding 'GBK','utf-8'}.readlines
 => ["你好\n"] 

#11 楼 @fsword #12 楼 @hooopo 学习了,我开始全面启用 1.9 的时间并不长,不过看起来 Ruby 的字符编码变得很强大了啊,顺便问一下在 Ruby 1.9 下面,怎么 detect 任意文本文件的编码?

#13 楼 @lgn21st detect 编码这种事情理论上不可能 100% 的,所以我估计标准库不会支持它

IE 和 The Unarchiver (or Stuffit ?) 有实作依统计方式判断编码,不过既然是统计就会有误差

#13 楼 @lgn21st 这个东西不太靠谱。

pure ruby 的解决方案是rchardet19.在gitlabhq项目的试用情况的话,很不理想。

之后就转用charlock_holmes了。这个依赖一个 c 库 libicu-dev. 效果比 rchardet19 好一些了。但是达不到完美。但是也就只能这样了~

#15 楼 @chitsaou 这东西文本越长准确率越高,所以一般网页判断的结果都很准确。。

感谢各位,问题得到解决。

print 'come from macbook most valueable edition'

供参考:

#encoding: UTF-8

File.open(STAT_FILE, :encoding => 'utf-8').each_line do |line|
  puts line.strip.split("\t")
en
需要 登录 后方可回复, 如果你还没有账号请 注册新账号